HDU 校 赛 | 2019 멀티 - 대학 교육 대회 (6)

2019 멀티 - 대학 교육 대회 (6)

http://acm.hdu.edu.cn/contests/contest_show.php?cid=853

1002 넌센스 시간

마법의 비교 ...이 문제는 하나의 결론이다 : 길이 \ (N- \) 임의의 배열 증가 원하는 길이의 긴 순서 \ (O (\ SQRT N-) \) .

그래서 우리는 이전 버전과 삭제의 수, 폭력과 현재 거래 중 가장 긴 연속 상승 할 때마다 고려하고 삭제 \ (X \) 에 대한 문장 때 \ (X의 \) 하지의 현재 순서로, 다시 다시 평가됩니다 그렇지 않으면 상관없이.

데이터 랜덤 때문에 \ (X \) 시퀀스의 확률이다 \ (\ FRAC {. 1} {\ SQRT N-} \) , 그것은 바람직 강력한 수요이다 \ (\ SQRT n \)\ (\ RM LIS \) , 복잡성 그러므로 \ (O (N- \ n-SQRT \ 로그 N-) \) .

#include<bits/stdc++.h>
using namespace std;

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

#define lf double

#define pii pair<int,int >
#define vec vector<int >

#define pb push_back
#define mp make_pair
#define fr first
#define sc second

#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)

const int maxn = 1e6+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;

int p[maxn],k[maxn],vis[maxn],n,in[maxn],ans[maxn],len,f[maxn];

struct tree_array {
    int t[maxn];
    void clear() {for(int i=1;i<=n;i++) t[i]=0;}
    void modify(int x,int v) {for(;x<=n;x+=x&-x) t[x]=max(t[x],v);}
    int query(int x,int ans=0) {for(;x;x-=x&-x) ans=max(ans,t[x]);return ans;}
}T;

void get_lis() {
    T.clear();len=0;
    for(int i=1;i<=n;i++) {
        in[i]=0;if(vis[i]) continue;
        f[i]=T.query(p[i]-1)+1;
        T.modify(p[i],f[i]);len=max(len,f[i]);
    }int x=len,pre=1e9;
    for(int i=n;i;i--)
        if(f[i]==x&&p[i]<pre&&!vis[i]) x--,pre=p[i],in[i]=1;
    // puts("OK");
    // for(int i=1;i<=n;i++) printf("%d ",vis[i]);puts("");
    // for(int i=1;i<=n;i++) printf("%d ",in[i]);puts("");
}

void solve() {
    read(n);
    for(int i=1;i<=n;i++) read(p[i]);
    for(int i=1;i<=n;i++) read(k[i]);
    get_lis();ans[n+1]=len;
    for(int i=n;i;i--) {
        vis[k[i]]=1;
        if(in[k[i]]) get_lis();
        ans[i]=len;
    }for(int i=2;i<=n+1;i++) printf("%d%c",ans[i],i==n+1?'\n':' ');
}

void clear() {
    for(int i=1;i<=n;i++) vis[i]=0;
}

int main() {
    int t;read(t);while(t--) solve(),clear();
    return 0;
}

1005 설 미소

아주 지루한이 질문에 직접 열거, 스윕을 오른쪽 경계를 철회 만남 포인트 트리 라인을 던져 한 다음 최대 연속을 유지하고 잘이며, 마진을 떠났다.

#include<bits/stdc++.h>
using namespace std;

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

#define lf double
#define ll long long 

#define pii pair<int,int >
#define vec vector<int >

#define pb push_back
#define mp make_pair
#define fr first
#define sc second

#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)

const int maxn = 4e3+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;

struct data {int x,y,w;}a[maxn];
int n,r[maxn],lx,ly;

void init() {
    read(n);
    for(int i=1;i<=n;i++) read(a[i].x),read(a[i].y),read(a[i].w);
    for(int i=1;i<=n;i++) r[i]=a[i].x;
    sort(r+1,r+n+1),lx=unique(r+1,r+n+1)-r-1;
    for(int i=1;i<=n;i++) a[i].x=lower_bound(r+1,r+lx+1,a[i].x)-r;
    for(int i=1;i<=n;i++) r[i]=a[i].y;
    sort(r+1,r+n+1),ly=unique(r+1,r+n+1)-r-1;
    for(int i=1;i<=n;i++) a[i].y=lower_bound(r+1,r+ly+1,a[i].y)-r;
}

int cmp(data a,data b) {return a.x<b.x||(a.x==b.x&&a.y<b.y);}

#define ls p<<1
#define rs p<<1|1
#define mid ((l+r)>>1)

struct segment_tree {
    ll mx[maxn<<2],mxl[maxn<<2],mxr[maxn<<2],sum[maxn<<2];

    void update(int p) {
        mx[p]=max(mx[ls],mx[rs]);
        mx[p]=max(mx[p],max(mxl[rs]+sum[ls],mxr[ls]+sum[rs]));
        mx[p]=max(mx[p],mxl[rs]+mxr[ls]);
        mxl[p]=max(mxl[ls],sum[ls]+mxl[rs]);
        mxr[p]=max(mxr[rs],sum[rs]+mxr[ls]);
        sum[p]=sum[ls]+sum[rs];
    }
    
    void modify(int p,int l,int r,int x,int v) {
        if(l==r) return sum[p]+=v,mxl[p]=mxr[p]=mx[p]=max(0ll,sum[p]),void();
        if(x<=mid) modify(ls,l,mid,x,v);
        else modify(rs,mid+1,r,x,v);
        update(p);
    }

    void clear(int p,int l,int r) {
        mx[p]=mxl[p]=mxr[p]=sum[p]=0;
        if(l==r) return ;
        clear(ls,l,mid);clear(rs,mid+1,r);
    }
}T;

void solve() {
    init();sort(a+1,a+n+1,cmp);int pps=1;ll ans=0;
    for(int i=1;i<=lx;i++) {
        T.clear(1,1,ly);while(a[pps].x!=i) pps++;
        int p=pps;
        for(int j=i;j<=lx;j++) {
            while(a[p].x==j) T.modify(1,1,ly,a[p].y,a[p].w),p++;
            ans=max(ans,T.mx[1]);
        }
    }printf("%lld\n",ans);
    for(int i=1;i<=n;i++) a[i].x=a[i].y=a[i].w=0;
}

int main() {
    int t;read(t);while(t--) solve();
    return 0;
}

멀리 (1006)

이것은 매우 흥미로운 질문, 우리는 첫 번째 사용 \ (\ N-) 에 평면에서 포인트 \ (N ^ 2 \) 블록의 절대 값은 각 블록에가 없다.

주목 (\ {\ RM LCM}는 (2,3,4,5)은 60 \를 =) 수평 및 수직 좌표 열거 답변에 더하여, 각 블록에 대해, (60 \) \ 나머지 후 \ (O (N) \ ) 판정 함께 불법 \ (O (1) \) 통계 않음 잘.

#include<bits/stdc++.h>
using namespace std;

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

#define lf double

#define pii pair<int,int >
#define vec vector<int >

#define pb push_back
#define mp make_pair
#define fr first
#define sc second

#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
#define ll long long 

const int maxn = 1e2+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;

struct data {int x,y,k,t;}a[maxn];
int lx[maxn],ly[maxn],n,m;
ll ans;

int calc(int l,int r) {return l>=r?0:(r-l-1)/60+1;}

int check(int x,int y) {
    for(int i=1;i<=n;i++) if((abs(x-a[i].x)+abs(y-a[i].y))%a[i].k!=a[i].t) return 0;
    return 1;
}

void solve() {
    read(n),read(m);ans=0;
    for(int i=1;i<=n;i++)
        read(a[i].x),lx[i]=a[i].x,read(a[i].y),ly[i]=a[i].y,read(a[i].k),read(a[i].t);
    sort(lx+1,lx+n+1);
    sort(ly+1,ly+n+1);
    ly[n+1]=m+1,lx[n+1]=m+1;
    for(int i=0;i<=n;i++) {
        if(lx[i+1]-lx[i]<=0) continue;
        for(int j=0;j<=n;j++) {
            if(ly[j+1]-ly[j]<=0) continue;
            for(int a=0;a<60;a++)
                for(int b=0;b<60;b++) 
                    if(check(lx[i]+a,ly[j]+b)) 
                        ans+=1ll*calc(lx[i]+a,lx[i+1])*calc(ly[j]+b,ly[j+1]);
        }
    }printf("%lld\n",ans);
}

void clear() {
    
}

int main() {
    int t;read(t);while(t--) solve(),clear();
    return 0;
}

1008 TDL

주목 \ (m의 \)이 작고, \ (f는 (N, m) -n \) 상기 대응 부 (\ m의 \) 작은 \ N- (\) 의 소수, 극단적 인 경우를 고려하여, 분리하기 전에 \ (m + \ n 개의 로그 \를 ) 소수 확실히 얻을 수있다.

그래서 직접 폭력 열거 \ (F (N, M) -n \) 대답은, 당신은 계산할 수있는 방법을 많이 \을 (N \) , 줄 (n \) \을 다시 확인한 후 (F를 \을 (N, M) - N \) 너무 많이 열거되지 않습니다.

그런 다음 모든 (N- \) \ 충분히 가지고 최소값.

#include<bits/stdc++.h>
using namespace std;

#define int long long 

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

#define lf double

#define pii pair<int,int >
#define vec vector<int >

#define pb push_back
#define mp make_pair
#define fr first
#define sc second

#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)

const int maxn = 1e6+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;

int m,k;

void solve() {
    read(k),read(m);int res=2e18;
    for(int a=m;a<=1000;a++) {
        int n=k^a,ans=0,cnt=0;
        for(int i=1;i<=1000;i++) {
            if(__gcd(i,n)==1) cnt++;
            if(cnt==m) {ans=i;break;}
        }if(a==ans) res=min(n,res);
    }if(res>1e18) puts("-1");else write(res);
}

signed main() {
    int t;read(t);while(t--) solve();
    return 0;
}

1010 말도 네티즌

형이상학 나무 파티션과 같은 스칼라 연산자는,하지만 난 빨리 표준 사업자보다 폭력적인 실행을 쓴 \ (10 \) 번 ....

(그럼 가자)

#include<bits/stdc++.h>
using namespace std;

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

#define lf double

#define pii pair<int,int >
#define vec vector<int >

#define pb push_back
#define mp make_pair
#define fr first
#define sc second

#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
#define iter map<int,int > :: iterator
#define for_map(i,x) for(iter i=x.begin();i!=x.end();i++) 

const int maxn = 3e3+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;

int n,m,head[maxn],tot,w[maxn],ans;
struct edge{int to,nxt;}e[maxn<<1];

void ins(int u,int v) {e[++tot]=(edge){v,head[u]},head[u]=tot;}

map<int,int > f[maxn],now[2];

void add(int &x,int y) {x+=y;if(x>=mod) x-=mod;}

void dfs(int x,int fa) {
    for(int i=head[x];i;i=e[i].nxt)
        if(e[i].to!=fa) dfs(e[i].to,x);
    int t=0;now[t][w[x]]=1;
    for(int E=head[x];E;E=e[E].nxt) {
        int v=e[E].to;if(v==fa) continue;
        for_map(i,now[t]) {
            for_map(j,f[v]) 
                if(1ll*i->fr*j->fr<=m) {
                    int r=i->fr*j->fr;
                    add(now[t^1][r],1ll*i->sc*j->sc%mod);
                } else break;
            add(now[t^1][i->fr],i->sc);
        }
        now[t].clear();t^=1;
    }f[x]=now[t];now[t].clear();
    for_map(i,f[x]) add(ans,i->sc);
    for(int i=head[x];i;i=e[i].nxt) f[e[i].to].clear();
}

void solve() {
    read(n),read(m);ans=0;
    for(int i=1;i<=n;i++) read(w[i]);
    for(int i=1,x,y;i<n;i++) read(x),read(y),ins(x,y),ins(y,x);
    dfs(1,0);f[1].clear();write(ans);
    for(int i=1;i<=n;i++) head[i]=0;tot=0;
}

int main() {
    int t;read(t);while(t--) solve();
    return 0;
}

1012 그대로 리얼

관객 물 문제의 대부분의 루트가 작은 힙을하기 때문에, 모든 선거의 가장 큰 미세.

#include<bits/stdc++.h>
using namespace std;

#define int long long 

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

#define lf double

#define pii pair<int,int >
#define vec vector<int >

#define pb push_back
#define mp make_pair
#define fr first
#define sc second

#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)

const int maxn = 1e6+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;

int n,t[maxn],vis[maxn];

priority_queue<pair<int,int > > q;

void solve() {
    read(n);
    for(int i=1;i<=n;i++) vis[i/2]=1,read(t[i]);
    for(int i=1;i<=n;i++) if(!vis[i]) q.push(mp(t[i],i));
    int a=0,b=0;
    for(int i=1;i<=n;i++) {
        int x=q.top().second;q.pop();
        if(x/2&&vis[x/2]) q.push(mp(t[x/2],x/2)),vis[x/2]=0;
        if(i&1) a+=t[x];else b+=t[x];
    }printf("%lld %lld\n",a,b);
}

void clear() {
    for(int i=1;i<=n;i++) vis[i]=0;
}

signed main() {
    int T;read(T);while(T--) solve(),clear();
    return 0;
}

추천

출처www.cnblogs.com/hbyer/p/11325410.html