码迷,mamicode.com
首页 > 其他好文 > 详细

弹飞绵羊

时间:2017-12-26 22:46:53      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:print   printf   query   space   ret   read   pop   std   clu   

#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;
}

弹飞绵羊

标签:print   printf   query   space   ret   read   pop   std   clu   

原文地址:https://www.cnblogs.com/qdscwyy/p/8120237.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!