首页 > 代码库 > BZOJ 2002 LCT板子题

BZOJ 2002 LCT板子题

思路:

LCT啊...

(分块也行)

不过YOUSIKI出了一道“弹飞大爷” 就不能用分块水过去了

//By SiriusRen
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=200050;
int fa[N],ch[N][2],rev[N],size[N],n,op,q[N],top,a[N],m,xx,yy;
bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void push_up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}
void push_down(int x){if(rev[x])rev[x]=0,rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,swap(ch[x][0],ch[x][1]);}
void rotate(int p){
    int q=fa[p],y=fa[q],f=(ch[q][1]==p);
    ch[q][f]=ch[p][!f],fa[ch[q][f]]=q;
    ch[p][!f]=q,fa[p]=y;
    if(!isroot(q)){
        if(ch[y][0]==q)ch[y][0]=p;
        if(ch[y][1]==q)ch[y][1]=p;
    }fa[q]=p;push_up(q);
}
void splay(int x){
    q[++top]=x;
    for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
    while(top)push_down(q[top--]);
    for(int y=fa[x];!isroot(x);rotate(x),y=fa[x])if(!isroot(y)){
        if((ch[y][0]==x)^(ch[fa[y]][0]==y))rotate(x);
        else rotate(y);
    }push_up(x);
}
void access(int x){for(int t=0;x;t=x,x=fa[x])splay(x),ch[x][1]=t,push_up(x);}
void makeroot(int x){access(x),splay(x),rev[x]^=1;}
void link(int x,int y){makeroot(x),fa[x]=y;}
void cut(int x,int y){makeroot(x),access(y),splay(y);ch[y][0]=fa[x]=0;}
void split(int x,int y){makeroot(x),access(y),splay(y);}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)link(i,a[i]+i>n?n+1:a[i]+i);
    scanf("%d",&m);
    while(m--){
        scanf("%d%d",&op,&xx),xx++;
        if(op==1)split(n+1,xx),printf("%d\n",size[xx]-1);
        else scanf("%d",&yy),cut(xx,xx+a[xx]>n?n+1:xx+a[xx]),a[xx]=yy,link(xx,xx+a[xx]>n?n+1:xx+a[xx]);
    }
}

 

BZOJ 2002 LCT板子题