2016-05-30 11:51:59
用一个next数组,记录点x的下一个点是哪个
查询时,moveroot(n+1),access(x),splay(x) ,输出size[ch[x][0]]即为答案
更改时,cut(x,next[x]) link(x,min(x+k,n+1))
记得splay旋转后要更新size
1 #include<bits/stdc++.h> 2 #define N 200005 3 using namespace std; 4 int read(){ 5 int x=0,f=1;char ch=getchar(); 6 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 7 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 8 return x*f; 9 } 10 int n,m,next[N]; 11 namespace LCT{ 12 int ch[N][2],fa[N],sz[N];bool rev[N]; 13 inline bool isroot(int x){ 14 if(ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x)return 1;return 0; 15 } 16 inline void pushdown(int x){ 17 if(rev[x]){ 18 rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;rev[x]=0; 19 swap(ch[x][0],ch[x][1]); 20 } 21 } 22 inline void pushup(int x){ 23 sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; 24 } 25 void rotate(int x){ 26 int y=fa[x],k=ch[y][1]==x; 27 if(!isroot(y))ch[fa[y]][ch[fa[y]][1]==y]=x; 28 fa[x]=fa[y]; 29 fa[ch[x][!k]]=y; 30 fa[y]=x; 31 ch[y][k]=ch[x][!k]; 32 ch[x][!k]=y; 33 pushup(y);pushup(x); 34 } 35 void Pushdown(int x){ 36 if(!isroot(x))Pushdown(fa[x]); 37 pushdown(x); 38 } 39 void splay(int x){ 40 Pushdown(x); 41 for(int y=fa[x];!isroot(x);y=fa[x]){ 42 if(!isroot(y)){ 43 if((ch[fa[y]][ch[fa[y]][1]==y])!=(ch[y][1]==x))rotate(x); 44 else rotate(y); 45 }rotate(x); 46 } 47 } 48 inline void access(int x){ 49 int y=0; 50 while(x){ 51 splay(x); 52 ch[x][1]=y; 53 x=fa[y=x]; 54 } 55 } 56 inline void moveroot(int x){ 57 access(x);splay(x);rev[x]^=1; 58 } 59 inline void link(int x,int y){ 60 moveroot(x);fa[x]=y;splay(x); 61 } 62 inline void cut(int x,int y){ 63 moveroot(x);access(y);splay(y);ch[y][0]=fa[x]=0; 64 } 65 inline int query(int x){ 66 moveroot(n+1);access(x);splay(x); 67 return sz[ch[x][0]]; 68 } 69 } 70 int main(){ 71 n=read(); 72 for(int i=1;i<=n;i++){ 73 int x=read(); 74 LCT::fa[i]=x+i;LCT::sz[i]=1; 75 if(LCT::fa[i]>n)LCT::fa[i]=n+1; 76 next[i]=LCT::fa[i]; 77 } 78 m=read(); 79 while(m--){ 80 int t=read(); 81 if(t==1)printf("%d\n",LCT::query(read()+1)); 82 else { 83 int x=read(),y=read();x++; 84 int t=min(n+1,x+y); 85 LCT::cut(x,next[x]);LCT::link(x,t);next[x]=t; 86 } 87 } 88 return 0; 89 }