zoukankan      html  css  js  c++  java
  • bzoj 4129: Haruna’s Breakfast

    传送门

    树上带修莫队的模板。

    主要是查询的时候,一开始脑子抽了想log修改log查询显然会T到死,然而O1修改根号查询就好了,直接分块维护。

    注意修改每次改回去的到时候改回的是上一次修改的颜色不是它本来的颜色,WA了好久。。。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<ctime>
    const int N=5e4+7; 
    typedef long long LL;
    using namespace std;
    int n,m,v[N],pr[N],is[N],ls[N],ans[N],sum[250],cnt[N],vis[N],cq,cc;
    
    template<typename T> void read(T &x) {
        T f=1; x=0; char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    int ecnt,fir[N],nxt[N<<1],to[N<<1];
    void add(int u,int v) {
        nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
        nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
    }
    
    int dfn[N],dfs_clock,sta[N],top,w,bl[N],R[N],f[N][20],tot; 
    void dfs(int x,int fa) {
        dfn[x]=++dfs_clock;
        R[x]=R[fa]+1;
        f[x][0]=fa;
        int low=top;
        for(int i=1;i<20;i++)
            f[x][i]=f[f[x][i-1]][i-1];
        for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
            dfs(to[i],x);
            if(top-low>=w) {
                tot++;
                while(top>low) {
                    int y=sta[top--];
                    bl[y]=tot;
                }
            }
        }
        sta[++top]=x;
    }
    
    struct node {
        int x,y,ti;
        node(){}
        node(int x,int y,int ti):x(x),y(y),ti(ti){}
        friend bool operator <(const node&A,const node&B) {
            return bl[A.x]<bl[B.x]||(bl[A.x]==bl[B.x]&&bl[A.y]<bl[B.y]);
        }
    }qs[N],cg[N];
    
    int qry() {
        for(int i=0;i<=(n/w+1);i++) 
            if(sum[i]!=w) 
                for(int j=0;j<w;j++) 
                    if(!cnt[i*w+j]) return i*w+j;
    }
    
    void rev(int x,int f) {
        if(f) {
            if(v[x]>=n) return;
            cnt[v[x]]++;
            if(cnt[v[x]]==1) sum[v[x]/w]++;
        }
        else {
            if(v[x]>=n) return;
            cnt[v[x]]--;
            if(!cnt[v[x]]) sum[v[x]/w]--;
        }
    }
    
    int lca(int x,int y) {
        if(R[x]<R[y]) swap(x,y);
        for(int i=19;i>=0;i--) 
            if(R[f[x][i]]>=R[y])
                x=f[x][i];
        if(x==y) return x;
        for(int i=19;i>=0;i--)
            if(f[x][i]!=f[y][i])
                x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    
    void change(int x,int y) {
        int z=lca(x,y);
        for(int i=x;i!=z;i=f[i][0])
            rev(i,vis[i]^=1);
        for(int i=y;i!=z;i=f[i][0])
            rev(i,vis[i]^=1);
    }
    
    void solve() {
        sort(qs+1,qs+cq+1);
        int now=0;
        for(int i=1;i<=cq;i++) {
            while(now+1<=cc&&cg[now+1].ti<=qs[i].ti) {
                now++;
                if(vis[cg[now].x]) rev(cg[now].x,0); 
                v[cg[now].x]=cg[now].y; 
                if(vis[cg[now].x]) rev(cg[now].x,1);
            }
            while(now&&cg[now].ti>qs[i].ti) {
                if(vis[cg[now].x]) rev(cg[now].x,0);
                v[cg[now].x]=pr[now];
                if(vis[cg[now].x]) rev(cg[now].x,1);
                now--;
            }
            if(i==1) change(qs[i].x,qs[i].y);
            else {
                change(qs[i-1].x,qs[i].x);
                change(qs[i-1].y,qs[i].y);
            } 
            int z=lca(qs[i].x,qs[i].y);
            rev(z,vis[z]^=1);
            ans[qs[i].ti]=qry();
            rev(z,vis[z]^=1);
        }
    }
    
    int main() {
        read(n); read(m);
        for(int i=1;i<=n;i++) { read(v[i]); ls[i]=v[i];}
        for(int i=1;i<n;i++) {
            int u,v;
            read(u); read(v);
            add(u,v);
        }
        for(int i=1;i<=m;i++) {
            int t,u,vv;
            read(t); read(u); read(vv);
            if(t==0) {
                cg[++cc]=node(u,vv,i);
                pr[cc]=ls[u]; ls[u]=vv;
                is[i]=1;
            }
            else qs[++cq]=node(u,vv,i);
        }
        w=sqrt(n);
        dfs(1,0);
        if(top) tot++; 
        while(top) bl[sta[top--]]=tot; 
        sort(qs+1,qs+cq+1);
        solve();
        for(int i=1;i<=m;i++) if(!is[i]) printf("%d
    ",ans[i]);
        return 0;
    }
    View Code
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    using namespace std;
    
    int main() {
        srand(time(NULL));
        int n=rand()%100+1,m=rand()%100+1;
        printf("%d %d
    ",n,m);
        for(int i=1;i<=n;i++) {
            int x=rand()%n;
            printf("%d ",x); 
        } puts("");
        for(int i=2;i<=n;i++) {
            int x=rand()%(i-1)+1;
            printf("%d %d
    ",i,x);
        }
        for(int i=1;i<=m;i++) {
            int t=rand()%2,x=rand()%n+1,y=rand()%n+1;
            printf("%d %d %d
    ",t,x,y);
        }
        return 0;
    }
    rand
  • 相关阅读:
    Codeforces Beta Round #18 (Div. 2 Only) C. Stripe 前缀和
    Codeforces Round #309 (Div. 1) C. Love Triangles dfs
    Codeforces Round #309 (Div. 1) B. Kyoya and Permutation 构造
    Codeforces Round #309 (Div. 2) C. Kyoya and Colored Balls 排列组合
    Codeforces Round #309 (Div. 2) B. Ohana Cleans Up 字符串水题
    Codeforces Round #309 (Div. 2) A. Kyoya and Photobooks 字符串水题
    Codeforces Beta Round #13 E. Holes 分块暴力
    Codeforces Beta Round #12 (Div 2 Only) D. Ball sort/map
    Codeforces Beta Round #6 (Div. 2 Only) E. Exposition multiset
    Codeforces Beta Round #5 E. Bindian Signalizing 并查集
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8301649.html
Copyright © 2011-2022 走看看