BZOJ

来源:互联网 发布:小神龙俱乐部停播 知乎 编辑:程序博客网 时间:2024/06/03 19:51

BZOJ - 3674
考虑用可持久化线段树维护 fadeep 数组。并且按秩合并。
这样复杂度就是 O(nlog2n) 了。

代码里没对 deep 数组持久化。。。不过好像没什么影响。

#include<bits/stdc++.h>using namespace std;const int N=2e5+7;int fa[N*25],ls[N*25],rs[N*25],tot,d[N*25],n,root[N];void build(int &rt,int l,int r){    rt=++tot;    if(l==r)    {        d[rt]=1;        fa[rt]=l;        return ;    }    int m=(l+r)>>1;    build(ls[rt],l,m);    build(rs[rt],m+1,r);}void update(int &rt,int last,int l,int r,int x,int y){    rt=++tot;    ls[rt]=ls[last];    rs[rt]=rs[last];    if(l==r)    {        fa[rt]=y;        return ;    }    int m=(l+r)>>1;    if(x<=m) update(ls[rt],ls[last],l,m,x,y);    else update(rs[rt],rs[last],m+1,r,x,y);}void add(int rt,int l,int r,int y){    if(l==r)    {        ++d[y];        return ;    }    int m=(l+r)>>1;    if(y<=m) add(ls[rt],l,m,y);    else add(rs[rt],m+1,r,y);}int query(int rt,int l,int r,int v){    if(l==r) return rt;    int m=(l+r)>>1;    if(v<=m) return query(ls[rt],l,m,v);    else return query(rs[rt],m+1,r,v);}int f(int x,int rt){    int p=query(rt,1,n,x);    if(x==fa[p]) return p;    else return f(fa[p],rt);}int main(){    int m,ans=0;    scanf("%d%d",&n,&m);    build(root[0],1,n);    for(int i=1;i<=m;++i)    {        int op,x,y,k;        scanf("%d",&op);        if(op==1)        {            scanf("%d%d",&x,&y);            x=x^ans;y=y^ans;            x=f(x,root[i-1]);y=f(y,root[i-1]);            if(fa[x]==fa[y]) continue;            if(d[x]>d[y]) swap(x,y);            update(root[i],root[i-1],1,n,fa[x],fa[y]);            if(d[x]==d[y]) add(root[i],1,n,fa[y]);        }        else if(op==2)        {            scanf("%d",&k);            k=k^ans;            root[i]=root[k];        }        else        {            scanf("%d%d",&x,&y);            x^=ans;y^=ans;            x=f(x,root[i-1]);y=f(y,root[i-1]);            root[i]=root[i-1];            printf("%d\n",ans=(fa[x]==fa[y]));        }    }    return 0;}
原创粉丝点击