1. 程式人生 > >[BZOJ2002][Hnoi2010]Bounce彈飛綿羊 LCT

[BZOJ2002][Hnoi2010]Bounce彈飛綿羊 LCT

維護 turn -s else sans bool ring 操作 bounce

題目鏈接: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 }

[BZOJ2002][Hnoi2010]Bounce彈飛綿羊 LCT