#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int maxn=200010; struct node{ int ls,rs,fa,is_root; }tr[maxn]; int n,m,siz[maxn],k[maxn]; void update(int x){ siz[x]=1; if(tr[x].ls)siz[x]+=siz[tr[x].ls]; if(tr[x].rs)siz[x]+=siz[tr[x].rs]; } void rx(int x){ int y=tr[x].fa,z=tr[y].fa; tr[y].ls=tr[x].rs; if(tr[x].rs)tr[tr[x].rs].fa=y; tr[x].rs=y;tr[y].fa=x; tr[x].fa=z; if(z&&!tr[y].is_root){//注意这句判断,辅助树之间的边是单向的; if(tr[z].ls==y)tr[z].ls=x;else tr[z].rs=x; } if(tr[y].is_root)tr[x].is_root=1,tr[y].is_root=0; update(y);update(x); } void lx(int x){ int y=tr[x].fa,z=tr[y].fa; tr[y].rs=tr[x].ls; if(tr[x].ls)tr[tr[x].ls].fa=y; tr[x].ls=y;tr[y].fa=x; tr[x].fa=z; if(z&&!tr[y].is_root){ if(tr[z].ls==y)tr[z].ls=x;else tr[z].rs=x; } if(tr[y].is_root)tr[x].is_root=1,tr[y].is_root=0; update(y);update(x); } void splay(int x){ while(!tr[x].is_root){ int y=tr[x].fa,z=tr[y].fa; if(tr[y].is_root){if(tr[y].ls==x)rx(x);else lx(x);} else{ if(tr[z].ls==y&&tr[y].ls==x){rx(y);rx(x);} else if(tr[z].ls==y&&tr[y].rs==x){lx(x);rx(x);} else if(tr[z].rs==y&&tr[y].ls==x){rx(x);lx(x);} else{lx(y);lx(x);} } } } void ace(int x){ int y=0; do{ splay(x); tr[tr[x].rs].is_root=1; tr[tr[x].rs=y].is_root=0; update(x); x=tr[y=x].fa; }while(x); } void link(int u,int v){//虽然说是link,但也包含和原来的断开然后和新的连上的两个过程 if(v>n)v=0; ace(u);splay(u); tr[tr[u].ls].is_root=1; tr[tr[u].ls].fa=0;tr[u].ls=0; tr[u].fa=v;update(u); } int query(int x){ ace(x);splay(x); return siz[tr[x].ls]+1; } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i){ tr[i].is_root=siz[i]=1; tr[i].fa=tr[i].ls=tr[i].rs=0; } for(int i=1;i<=n;++i){ scanf("%d",&k[i]); link(i,i+k[i]); } scanf("%d",&m); int op,pos,cha; for(int i=1;i<=m;++i){ scanf("%d%d",&op,&pos); if(op==1)printf("%d ",query(pos+1)); else{ scanf("%d",&cha); link(pos+1,pos+cha+1); } } //system("pause"); return 0; }