思路:
LCT啊...
(分块也行)
不过YOUSIKI出了一道“弹飞大爷” 就不能用分块水过去了
//By SiriusRen #include <cstdio> #include <algorithm> using namespace std; const int N=200050; int fa[N],ch[N][2],rev[N],size[N],n,op,q[N],top,a[N],m,xx,yy; bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} void push_up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;} void push_down(int x){if(rev[x])rev[x]=0,rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,swap(ch[x][0],ch[x][1]);} void rotate(int p){ int q=fa[p],y=fa[q],f=(ch[q][1]==p); ch[q][f]=ch[p][!f],fa[ch[q][f]]=q; ch[p][!f]=q,fa[p]=y; if(!isroot(q)){ if(ch[y][0]==q)ch[y][0]=p; if(ch[y][1]==q)ch[y][1]=p; }fa[q]=p;push_up(q); } void splay(int x){ q[++top]=x; for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i]; while(top)push_down(q[top--]); for(int y=fa[x];!isroot(x);rotate(x),y=fa[x])if(!isroot(y)){ if((ch[y][0]==x)^(ch[fa[y]][0]==y))rotate(x); else rotate(y); }push_up(x); } void access(int x){for(int t=0;x;t=x,x=fa[x])splay(x),ch[x][1]=t,push_up(x);} void makeroot(int x){access(x),splay(x),rev[x]^=1;} void link(int x,int y){makeroot(x),fa[x]=y;} void cut(int x,int y){makeroot(x),access(y),splay(y);ch[y][0]=fa[x]=0;} void split(int x,int y){makeroot(x),access(y),splay(y);} int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=n;i++)link(i,a[i]+i>n?n+1:a[i]+i); scanf("%d",&m); while(m--){ scanf("%d%d",&op,&xx),xx++; if(op==1)split(n+1,xx),printf("%d ",size[xx]-1); else scanf("%d",&yy),cut(xx,xx+a[xx]>n?n+1:xx+a[xx]),a[xx]=yy,link(xx,xx+a[xx]>n?n+1:xx+a[xx]); } }