题意:等一等 这个是中文题啊
解法:其实就是维护一个森林 然后求出某个树上节点得祖先的个数就可以了 模型很好的 出人意料
#include<cstdio>
#include<math.h>
#include<stdlib.h>
using namespace std;
#define ls ch[rt][0]
#define rs ch[rt][1]
#define MAXN 222222
int ch[MAXN][2],fa[MAXN],num[MAXN];
bool _rt[MAXN];
inline void down(int rt){}
inline void up(int rt){num[rt]=num[ls]+num[rs]+1;}
inline void _vis(int rt){
if(!_rt[rt])_vis(fa[rt]);
down(rt);
}
inline void rot(int rt){
int f=fa[rt],side=ch[f][1]==rt,ll=ch[rt][!side];
fa[ll]=f,ch[f][side]=ll;
fa[rt]=fa[f];
if(_rt[f])_rt[f]=0,_rt[rt]=1;
else ch[fa[f]][ch[fa[f]][1]==f]=rt;
fa[f]=rt,ch[rt][!side]=f;
up(f),up(rt);
}
inline void splay(int rt){
_vis(rt);
while(!_rt[rt]){
int f=fa[rt],ff=fa[f];
if(_rt[f])rot(rt);
else if((ch[f][1]==rt)==(ch[ff][1]==f))rot(f),rot(rt);
else rot(rt),rot(rt);
}up(rt);
}
inline int ace(int rt){
int y=0;
for(;rt;y=rt,rt=fa[rt]){
splay(rt);
_rt[rs]=1,rs=y,_rt[rs]=0;
up(rt);
}return y;
}
int a[MAXN],m,n,op,u,v;
inline void init(){
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
for(int rt=0;rt<=n+1;++rt){
fa[rt]=ls=rs=0;_rt[rt]=1;num[rt]=1;
}
num[0]=0;
for(int i=1;i<=n;++i){
int t=i+a[i];
if(t>n+1)t=n+1;
fa[i]=t;
}
}
int main(){
while(~scanf("%d",&n)){
init();
scanf("%d",&m);
while(m--){
scanf("%d",&op);
if(op == 1){
scanf("%d",&u);u++;ace(u);
splay(u);
printf("%d\n",num[ch[u][0]]);
}
else{
scanf("%d%d",&u,&v);
u++;ace(u);splay(u);
fa[ch[u][0]]=fa[u];fa[u]=0;
_rt[ch[u][0]]=1;ch[u][0]=0;
up(u);
int t=u+v;
if(t>n+1)t=n+1;
fa[u]=t;
}
}
}
return 0;
}