【BZOJ】【2002】【HNOI2010】弹飞绵羊
呃这题的Hint写着splay启发式合并……但是蒟蒻不懂T_T只好写个简单的LCT来蒙混过关,就是时间效率上差劲的很……
不过能够一次AC心情也是蛮愉悦的~
1 /************************************************************** 2 Problem: 2002 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:1932 ms 7 Memory:6156 kb 8 ****************************************************************/ 9 10 //BZOJ 2002 11 #include<cstdio> 12 #include<cstdlib> 13 #include<cstring> 14 #include<iostream> 15 #include<algorithm> 16 #define rep(i,n) for(int i=0;i<n;++i) 17 #define F(i,j,n) for(int i=j;i<=n;++i) 18 #define D(i,j,n) for(int i=j;i>=n;--i) 19 using namespace std; 20 const int N=200010; 21 22 int c[N][2],fa[N],size[N],n,m,k[N],st[N],top=0; 23 bool rev[N]; 24 25 int read(){ 26 char ch=getchar(); 27 int sig=1,tmp=0; 28 while(ch<'0'||ch>'9') {if (ch=='-') sig=-1;ch=getchar();} 29 while(ch>='0' && ch<='9') {tmp=10*tmp+ch-'0';ch=getchar();} 30 return tmp*sig; 31 } 32 33 void Push_down(int x){ 34 if (rev[x]){ 35 rev[x]^=1; rev[c[x][0]]^=1; rev[c[x][1]]^=1; 36 swap(c[x][0],c[x][1]); 37 } 38 } 39 inline void Push_up(int x){ 40 size[x]=size[c[x][0]]+size[c[x][1]]+1; 41 } 42 bool isroot(int x){ 43 return c[fa[x]][0]!=x && c[fa[x]][1]!=x; 44 } 45 void rotate(int x){ 46 int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1; 47 if (!isroot(y)) c[z][c[z][1]==y]=x; 48 fa[x]=z; fa[y]=x; fa[c[x][r]]=y; 49 c[y][l]=c[x][r]; c[x][r]=y; 50 Push_up(y); Push_up(x); 51 } 52 void splay(int x){ 53 top=0; st[top++]=x; 54 for(int i=x;!isroot(i);i=fa[i]) 55 st[top++]=fa[i]; 56 while(top--) Push_down(st[top]); 57 58 while(!isroot(x)){ 59 int y=fa[x],z=fa[y]; 60 if (!isroot(y)){ 61 if (c[y][0]==x^c[z][0]==y) rotate(x); 62 else rotate(y); 63 } 64 rotate(x); 65 } 66 } 67 void access(int x){ 68 for(int t=0;x;t=x,x=fa[x]) 69 splay(x),c[x][1]=t,Push_up(x); 70 } 71 void makeroot(int x){ 72 access(x); splay(x); rev[x]^=1; 73 } 74 int find(int x){ 75 access(x); splay(x); 76 while(c[x][0]) x=c[x][0]; 77 return x; 78 } 79 void cut(int x,int y){ 80 makeroot(x); access(y); splay(y); 81 if (c[y][0]==x) c[y][0]=fa[x]=0; 82 } 83 void link(int x,int y){ 84 makeroot(x); fa[x]=y; 85 } 86 //LCT end 87 int main(){ 88 // freopen("input.txt","r",stdin); 89 n=read(); 90 F(i,1,n){ 91 k[i]=read(); 92 link(i,min(i+k[i],n+1)); 93 } 94 m=read(); 95 int x,y,z; 96 F(i,1,m){ 97 x=read(); y=read(); y++; 98 if (x==1) { 99 makeroot(n+1); 100 access(y);splay(y); 101 printf("%d\n",size[y]-1); 102 } 103 else if(x==2){ 104 z=read(); 105 cut(y,min(y+k[y],n+1)); 106 k[y]=z; 107 link(y,min(y+k[y],n+1)); 108 } 109 } 110 return 0; 111 }