zoukankan      html  css  js  c++  java
  • bzoj 4811: [Ynoi2017]由乃的OJ

    树链剖分,用zkw线段树维护每条链两个方向上对每一位的变换情况,由于位数较少,可以用两个unsigned long long表示

    #include<cstdio>
    typedef unsigned long long u64;
    const int N=100007;
    char buf[N*100],*ptr=buf-1;
    int _(){
        int x=0,c=*++ptr;
        while(c<48)c=*++ptr;
        while(c>47)x=x*10+c-48,c=*++ptr;
        return x;
    }
    u64 _u64(){
        u64 x=0;
        int c=*++ptr;
        while(c<48)c=*++ptr;
        while(c>47)x=x*10+c-48,c=*++ptr;
        return x;
    }
    int es[N*2],enx[N*2],e0[N],ep=2,tp[N];
    u64 v[N];
    int fa[N],sz[N],top[N],dep[N],son[N],id[N],idp=0,idr[N];
    int n,m,k;
    u64 vs[262777][4];
    void f1(int w,int pa){
        dep[w]=dep[fa[w]=pa]+1;
        sz[w]=1;
        for(int i=e0[w];i;i=enx[i]){
            int u=es[i];
            if(u!=pa){
                f1(u,w);
                sz[w]+=sz[u];
                if(sz[u]>sz[son[w]])son[w]=u;
            }
        }
    }
    void f2(int w,int tp){
        top[w]=tp;
        id[w]=++idp;
        idr[idp]=w;
        if(son[w])f2(son[w],tp);
        for(int i=e0[w];i;i=enx[i]){
            int u=es[i];
            if(u!=fa[w]&&u!=son[w])f2(u,u);
        }
    }
    int s1[107],p1,s2[107],p2,s3[10007],s4[10007],p3,p4;
    void find(int l,int r,int tp){
        p1=p2=0;
        for(l+=131071,r+=131073;r-l!=1;l>>=1,r>>=1){
            if(~l&1)s1[p1++]=l^1;
            if(r&1)s2[p2++]=r^1;
        }
        if(!tp){
            for(int i=0;i<p2;++i)s4[p4++]=s2[i];
            while(p1)s4[p4++]=s1[--p1];
        }else{
            for(int i=0;i<p2;++i)s3[p3++]=s2[i];
            while(p1)s3[p3++]=s1[--p1];
        }
    }
    #define cal(a,b,c0,c1) (a)=((~(b)&(c0))|((b)&(c1)))
    void init(int w,int tp,u64 v){
        u64*a=vs[w];
        if(tp==1){
            a[0]=a[2]=0ll&v;
            a[1]=a[3]=-1ll&v;
        }else if(tp==2){
            a[0]=a[2]=0ll|v;
            a[1]=a[3]=-1ll|v;
        }else if(tp==3){
            a[0]=a[2]=0ll^v;
            a[1]=a[3]=-1ll^v;
        }
    }
    void up(u64*a,u64*l,u64*r){
        cal(a[0],l[0],r[0],r[1]);
        cal(a[1],l[1],r[0],r[1]);
        cal(a[2],r[2],l[2],l[3]);
        cal(a[3],r[3],l[2],l[3]);
    }
    u64 _v0,_v1;
    void get(int x,int y){
        p3=p4=0;
        int a=top[x],b=top[y];
        while(a!=b){
            if(dep[a]>dep[b]){
                find(id[a],id[x],0);
                x=fa[a],a=top[x];
            }else{
                find(id[b],id[y],1);
                y=fa[b],b=top[y];
            }
        }
        if(dep[x]>dep[y]){
            find(id[y],id[x],0);
        }else{
            find(id[x],id[y],1);
        }
        u64 v0=0ll,v1=-1ll;
        for(int i=0;i<p4;++i){
            u64*a=vs[s4[i]];
            cal(v0,v0,a[2],a[3]);
            cal(v1,v1,a[2],a[3]);
        }
        while(p3){
            u64*a=vs[s3[--p3]];
            cal(v0,v0,a[0],a[1]);
            cal(v1,v1,a[0],a[1]);
        }
        _v0=v0,_v1=v1;
    }
    int main(){
        fread(buf,1,sizeof(buf),stdin)[buf]=0;
        n=_();m=_();k=_();
        for(int i=1;i<=n;++i){
            tp[i]=_();
            v[i]=_u64();
        }
        for(int i=1,a,b;i<n;++i){
            a=_();b=_();
            es[ep]=b;enx[ep]=e0[a];e0[a]=ep++;
            es[ep]=a;enx[ep]=e0[b];e0[b]=ep++;
        }
        f1(1,0);f2(1,1);
        for(int i=1;i<=n;++i)init(id[i]+131072,tp[i],v[i]);
        for(int i=131071;i;--i)up(vs[i],vs[i<<1],vs[i<<1|1]);
        for(int i=0;i<m;++i){
            int o=_(),x=_(),y=_();
            u64 z=_u64();
            if(o==1){
                get(x,y);
                u64 r=0,r0,r1;
                for(int i=63;i>=0;--i)if((r|1llu<<i)<=z){
                    cal(r0,r,_v0,_v1);
                    cal(r1,(r|1llu<<i),_v0,_v1);
                    if(r0<r1)r|=1llu<<i;
                }
                cal(r0,r,_v0,_v1);
                printf("%llu
    ",r0);
            }else{
                init(id[x]+131072,tp[x]=y,v[x]=z);
                for(int w=id[x]+131072>>1;w!=1;w>>=1)up(vs[w],vs[w<<1],vs[w<<1^1]);
            }
        }
        return 0;
    }
  • 相关阅读:
    BZOJ 1251 序列终结者(Splay)
    ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)
    POJ 2887 Big String(块状链表)
    BZOJ 1093 [ZJOI2007] 最大半连通子图(强联通缩点+DP)
    Codeforces Beta Round #13 C. Sequence (DP)
    Codeforces Round #184 (Div. 2) E. Playing with String(博弈)
    MemSQL start[c]up Round 2
    Codeforces Round #195 A B C 三题合集 (Div. 2)
    哈密尔顿回路总结
    最大团问题
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7416282.html
Copyright © 2011-2022 走看看