【lct】bzoj2002 [Hnoi2010]Bounce 弹飞绵羊
lct板子,此题主要有cut操作和link操作。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; #define maxn 200005 #define INF 2147483647 int fa[maxn],val[maxn],c[maxn][2],root,tot,siz[maxn]; bool delta[maxn],is_root[maxn]; void Maintain(int x) { siz[x]=siz[c[x][0]]+siz[c[x][1]]+1; } //void Mark(int x){ // if(x){ // delta[x]^=1; // } //} //void pushdown(int x){ // if(delta[x]){ // Mark(c[x][0]); // Mark(c[x][1]); // swap(c[x][0],c[x][1]); // delta[x]=0; // Maintain(x); // } //} //void NewNode(int &x,int Fa) //{ // x=++tot; // fa[x]=Fa; // c[x][0]=c[x][1]=0; // siz[x]=1; //} void Rotate(int x,bool flag) { int y=fa[x]; // pushdown(y); // pushdown(x); c[y][!flag]=c[x][flag]; if(c[x][flag]){ fa[c[x][flag]]=y; } if(fa[y] && c[fa[y]][c[fa[y]][1]==y]==y){ c[fa[y]][c[fa[y]][1]==y]=x; } fa[x]=fa[y]; c[x][flag]=y; fa[y]=x; if(is_root[y]){ is_root[y]=0; is_root[x]=1; } Maintain(y);
Maintain(x); } void Splay(int x) { if(!x || is_root[x]){ return; } // pushdown(x); int y; while(y=fa[x],(!is_root[x])){ if(is_root[y]){ Rotate(x,c[y][0]==x); } else{ if((c[y][0]==x)==(c[fa[y]][0]==y)){ Rotate(y,c[fa[y]][0]==y); } else{ Rotate(x,c[y][0]==x); y=fa[x]; } Rotate(x,c[y][0]==x); } } Maintain(x); } void Access(int x){ int y; Splay(x); while(fa[x]){ y=fa[x]; Splay(y); if(c[y][1]){ is_root[c[y][1]]=1; } is_root[x]=0; c[y][1]=x; Splay(x); } if(c[x][1]){ is_root[c[x][1]]=1; c[x][1]=0; } } int FindRoot(int x){ Access(x); Splay(x); while(c[x][0]){ x=c[x][0]; } return x; } void cut(int x){ Access(x); Splay(x); fa[c[x][0]]=0; if(c[x][0]){ is_root[c[x][0]]=1; } c[x][0]=0; } void link(int x,int y){ Access(x); Splay(x); // Mark(c[x][0]); Access(y); Splay(y); c[y][1]=x; fa[x]=y; is_root[x]=0; } int calc(int x){ Access(x); Splay(x); return siz[c[x][0]]+1; } int n,m; int main(){ // freopen("bzoj2002.in","r",stdin); // freopen("bzoj2002.out","w",stdout); int op,d,g; scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d",&d); fa[i]=(i+d<=n ? i+d : 0); c[i][0]=c[i][1]=0; siz[i]=1; delta[i]=0; is_root[i]=1; } scanf("%d",&m); for(int i=1;i<=m;++i){ scanf("%d%d",&op,&d); ++d; if(op==1){ printf("%d\n",calc(d)); } else{ scanf("%d",&g); cut(d); if(d+g<=n){ link(d,d+g); } } } return 0; }
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/