【BZOJ2002】弹飞绵羊

来源:互联网 发布:用友软件云南代理商 编辑:程序博客网 时间:2024/05/17 07:01

第一道LCT,纪念一下~

#include<iostream>#include<cstdio>#define maxn 200000using namespace std;int n;int ch[maxn+10][2],fa[maxn+10],sz[maxn+10];int rc(int f,int o){return ch[f][1]==o;}void pushup(int o){    if(!o)return;    sz[o]=sz[ch[o][0]]+sz[ch[o][1]]+1;}bool root(int o){return ch[fa[o]][0]!=o&&ch[fa[o]][1]!=o;}void rotate(int o){    int f=fa[o],r=rc(fa[o],o);    if(!root(f))fa[ch[fa[f]][rc(fa[f],f)]=o]=fa[f];    else fa[o]=fa[f];    fa[ch[f][r]=ch[o][r^1]]=f;    fa[ch[o][r^1]=f]=o;    pushup(f);    pushup(o);}void splay(int o){    while(!root(o)){        if(!root(fa[o])&&rc(fa[fa[o]],fa[o])==rc(fa[o],o))rotate(fa[o]);        rotate(o);    }}void access(int u){    int v=0;    while(u){        splay(u);        ch[u][1]=v;        pushup(u);        v=u;        u=fa[u];     }}void join(int v,int u){    access(v);    splay(v);    fa[ch[v][0]]=0;    ch[v][0]=0;    fa[v]=u;    access(v);}int main(){    freopen("2002.in","r",stdin);    scanf("%d",&n);    for(int i=1;i<=n;i++){        int a;        scanf("%d",&a);        fa[i]=min(n+1,i+a);    }    int m;    scanf("%d",&m);    while(m--){        int k,u;        scanf("%d%d",&k,&u);        u++;        if(k==1){            access(u);            splay(u);            printf("%d\n",sz[u]-1);        }else{            int c;            scanf("%d",&c);            join(u,min(n+1,u+c));        }    }    return 0;}
0 0
原创粉丝点击