uoj#158. 【清华集训2015】静态仙人掌

http://uoj.ac/problem/158

预处理dfs序,询问转为区间1的个数,用可持久化bitset预处理出所有可能的修改对应哪些位置,然后用一个bitset维护当前每个点的状态,修改时可以用xor实现

#include<bits/stdc++.h>
int _(){
    int x=0,c=getchar();
    while(c<48)c=getchar();
    while(c>47)x=x*10+c-48,c=getchar();
    return x;
}
const int N=55007;
typedef unsigned long long u64;
typedef u64 block[32];
typedef block *bits[32];
block pool[N*3],*pp=pool;
int n,m,q,fa[N],son[N],dep[N],dl[N],dr[N],cb;
std::vector<int>e[N];
int dfn[N],mxd[N],tk=0;
bits f[N],fl[N],fr[N];
void init(){
    std::queue<int>q;
    q.push(1);dep[1]=1;
    while(q.size()){
        int w=q.front();q.pop();
        for(unsigned i=0;i<e[w].size();++i){
            int u=e[w][i];
            if(!dep[u])q.push(u),fa[u]=w,dep[u]=dep[w]+1;
            else if(dep[u]==dep[w]&&w<u){
                for(int x=w,y=u,x0=u,y0=w;x!=y;x=fa[x],y=fa[y]){
                    dl[x]=dr[y]=1;
                    son[x]=x0,son[y]=y0;
                    x0=x,y0=y;
                }
            }
        }
    }
}
void dfs(int w){
    dfn[w]=++tk;
    for(unsigned i=0;i<e[w].size();++i){
        int u=e[w][i];
        if(dep[u]>dep[w]&&u!=son[w])dfs(u);
    }
    mxd[w]=tk;
    if(dep[son[w]]>dep[w]&&son[w])dfs(son[w]);
}
void cpy(bits a,bits b,int x){
    for(int i=0;i<cb;++i)a[i]=b[i];
    memcpy(a[x>>11]=++pp,b[x>>11],sizeof(block));
    (*pp)[x>>6&31]|=1llu<<(x&63);
}
void get(int w){
    if(f[w][0])return;
    get(fa[w]);
    cpy(f[w],f[fa[w]],dfn[w]);
}
void getr(int);
void getl(int w){
    if(fl[w][0])return;
    int u=dr[w]?son[w]:fa[w];
    if(u==fa[w]&&w!=son[u]){
        dl[u]?getr(u):getl(u);
        cpy(fl[w],dl[u]?fr[u]:fl[u],dfn[w]);
    }else{
        getl(u);
        cpy(fl[w],fl[u],dfn[w]);
    }
}
void getr(int w){
    if(fr[w][0])return;
    int u=dl[w]?son[w]:fa[w];
    if(u==fa[w]&&w!=son[u]){
        dl[u]?getr(u):getl(u);
        cpy(fr[w],dl[u]?fr[u]:fl[u],dfn[w]);
    }else{
        getr(u);
        cpy(fr[w],fr[u],dfn[w]);
    }
}
u64 ans[5007];
int test(int x){
    return ans[x>>6]>>(x&63)&1;
}
int q0(int l,int r){
    int l1=l>>6,r1=r>>6,s=0;
    if(l1==r1)for(int i=l;i<=r;++i)s+=test(i);
    else{
        for(int i=l;(i>>6)==l1;++i)s+=test(i);
        for(int i=r;(i>>6)==r1;--i)s+=test(i);
        for(int i=l1+1;i<r1;++i){
            u64 x=ans[i];
            s+=__builtin_popcount(x&0xffffffff);
            s+=__builtin_popcount(x>>32);
        }
    }
    return r-l+1-s;
}
void rev(bits w){
    u64*A=ans,*B;
    for(int i=0;i<cb;++i){
        B=*(w[i]);
        for(int j=0;j<32;j+=8){
            A[0]^=B[0];A[1]^=B[1];A[2]^=B[2];A[3]^=B[3];
            A[4]^=B[4];A[5]^=B[5];A[6]^=B[6];A[7]^=B[7];
            A+=8,B+=8;
        }
    }
}
int main(){
    n=_();m=_();q=_();
    cb=(n+1>>11)+1;
    for(int i=0;i<cb;++i)f[0][i]=fl[0][i]=fr[0][i]=pp;
    for(int i=1,a,b;i<=m;++i){
        a=_();b=_();
        e[a].push_back(b);
        e[b].push_back(a);
    }
    init();
    dfs(1);
    for(int i=1;i<=n;++i){
        get(i);
        getl(i);
        getr(i);
    }
    for(int i=1;i<=q;++i){
        int op=_(),x=_();
        if(op==1)rev(f[x]);
        else if(op==2)rev(dl[x]?fr[x]:fl[x]);
        else printf("%d
",q0(dfn[x],mxd[x]));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ccz181078/p/7418493.html