[BZOJ2002][Hnoi2010]Bounce弹飞绵羊 LCT
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002
建图,每次往后面跳就往目标位置连边,将跳出界的点设为同一个点。对于修改操作发现可以用LCT维护图的连通性,然后用size域维护跳的点的次数就行了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int inline readint(){ 6 int Num;char ch; 7 while((ch=getchar())<'0'||ch>'9');Num=ch-'0'; 8 while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0'; 9 return Num; 10 } 11 void outint(int x){ 12 if(x>=10) outint(x/10); 13 putchar(x%10+'0'); 14 } 15 int n,fa[200010],ch[200010][2],siz[200010]; 16 bool inline Isroot(int &x){ 17 return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; 18 } 19 void inline Pushup(int &x){ 20 siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; 21 } 22 void Rot(int x,int p){ 23 int y=fa[x],z=fa[y]; 24 fa[ch[x][!p]]=y;ch[y][p]=ch[x][!p]; 25 fa[x]=z;if(!Isroot(y)) ch[z][ch[z][1]==y]=x; 26 fa[y]=x;ch[x][!p]=y; 27 Pushup(y);Pushup(x); 28 } 29 void Splay(int x){ 30 while(!Isroot(x)){ 31 if(Isroot(fa[x])) Rot(x,ch[fa[x]][1]==x); 32 else{ 33 int y=fa[x],z=fa[y],p=ch[z][1]==y; 34 if(ch[y][p]==x) Rot(y,p),Rot(x,p); 35 else Rot(x,!p),Rot(x,p); 36 } 37 } 38 } 39 void Access(int x){ 40 for(int t=0;x;x=fa[x]){ 41 Splay(x); 42 ch[x][1]=t; 43 Pushup(x); 44 t=x; 45 } 46 } 47 void Link(int x,int y){ 48 Access(x);Splay(x); 49 fa[ch[x][0]]=0; 50 ch[x][0]=0; 51 fa[x]=y; 52 Pushup(x); 53 } 54 void Qry(int x){ 55 Access(x);Splay(x); 56 outint(siz[x]); 57 putchar('\n'); 58 } 59 int main(){ 60 n=readint(); 61 for(int i=1;i<=n;i++){ 62 int x=readint()+i; 63 fa[i]=x>n?0:x; 64 } 65 int m=readint(); 66 for(int i=1;i<=m;i++){ 67 int opt=readint(); 68 if(opt==1){ 69 int a=readint(); 70 Qry(a+1); 71 } 72 else{ 73 int a=readint(), 74 b=readint(); 75 Link(a+1,(a+b+1)>n?0:(a+b+1)); 76 } 77 } 78 return 0; 79 }