首页 > 代码库 > 【BZOJ】【2002】【HNOI2010】弹飞绵羊

【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 }
View Code

 

【BZOJ】【2002】【HNOI2010】弹飞绵羊