弹飞绵羊

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define N 10005
using namespace std;

void read(int &s){
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar());
    for(s=0;isdigit(ch);s=s*10+ch-'0',ch=getchar());
}
int n,m,a,b,c;
queue<int>que;
int ch[N][2];
int size[N];
int rev[N];
int fa[N];
int p[N];

bool isroot(int u){
    if(!fa[u])return true;
    return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}

void update(int x){
    if(!x)return;
    size[x]=1;
    if(ch[x][0])size[x]+=size[ch[x][0]];
    if(ch[x][1])size[x]+=size[ch[x][1]];
}

void Rotate(int u){
    bool d=ch[fa[u]][1]==u;
    int x=fa[u],y=fa[x];
    fa[u]=y;
    if(!isroot(x))ch[y][ch[y][1]==x]=u;
    ch[x][d]=ch[u][!d];fa[ch[u][!d]]=x;
    ch[u][!d]=x;fa[x]=u;
    update(x);
    update(u);
}

void push_down(int u){
    if(rev[u]){
        rev[ch[u][0]]^=1;
        swap(ch[ch[u][0]][0],ch[ch[u][0]][1]);
        rev[ch[u][1]]^=1;
        swap(ch[ch[u][1]][0],ch[ch[u][1]][1]);
        rev[u]^=1;
    }
}

void Splay(int u){
    int top=0;
    que.push(u);
    for(int i=u;!isroot(i);i=fa[i])
        que.push(fa[i]);
    top++;
    do{
        push_down(que.front());
        que.pop();
    }while(!que.empty());
    while(!isroot(u)){
        int x=fa[u],y=fa[x];
        if(!isroot(x)){
            if((ch[y][0]==x)^(ch[x][0]==u))Rotate(x);
            else Rotate(u);
        }
        Rotate(u);
    }
}

void Access(int u){
    int t=0;
    while(u){
        Splay(u);
        ch[u][1]=t;
        t=u;
        u=fa[u];
    }
}

void Rev(int u){
    Access(u);
    Splay(u);
    rev[u]^=1;
    swap(ch[u][0],ch[u][1]);
}

void Link(int x,int y){
    Rev(x);
    fa[x]=y;
    Splay(x);
}

void Cut(int x,int y){
    Rev(x);
    Access(y);
    Splay(y);
    ch[y][0]=fa[x]=0;
}

int Query(int x){
    Rev(n+1);
    Access(x);
    Splay(x);
    return size[ch[x][0]];
}

int main(){
    read(n);
    for(int i=1;i<=n;++i){
        read(p[i]);
        if(p[i]+i<=n)
            p[i]+=i;
        else p[i]=n+1;
        fa[i]=p[i];
        size[i]=1;
    }
    size[n+1]=1;
    read(m);
    for(int i=1;i<=m;++i){
        read(a);
        if(a==1){
            read(b);
            b+=1;
            printf("%d",Query(b));
        }
        else {
            read(b),read(c);
            ++b;
            Cut(b,p[b]);
            if(b+c<=n)p[b]=c+b;
            else p[b]=n+1;
            Link(b,p[b]);
        }
    }
    return 0;
}

posted @ 2017-12-26 22:00  Grary  阅读(123)  评论(0编辑  收藏  举报
博客园 首页 私信博主 编辑 关注 管理 新世界