您的位置:首页 > 其它

【BZOJ2002】弹飞绵羊

2015-11-18 19:35 267 查看
第一道LCT,纪念一下~

[code]#include<iostream>
#include<cstdio>
#define maxn 200000
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: