//预处理出以这个点为起点并跳出这个块的次数和位置 //更新一个点的弹力系数可以只更新这个点以及这个块内之前的点 #include<stdio.h> #include<algorithm> #include<string.h> #include<cmath> #include<iostream> using namespace std; const int N=2e5+10; struct node { //ahead为从该点跳的距离 int ahead; //step为跳到下一个块的所需步数 int step; //Next为跳到的下一个块 跳出Next为0 int Next; //pos为跳到下一个块的位置 int pos; }p[N]; int temp; int block[N]; int main() { int n,m,op; scanf("%d",&n); for(int i=0; i<n; i++) scanf("%d",&p[i].ahead); temp=sqrt(n); //分块 for(int i=0; i<n; i++) block[i]=i/temp+1; for(int i=n-1; i>=0; i--) { //如果在同一个块内 if(block[i+p[i].ahead]!=block[i]) { p[i].Next=block[i+p[i].ahead]; p[i].pos=i+p[i].ahead; p[i].step=1; } else { p[i].Next=p[i+p[i].ahead].Next; p[i].pos=p[i+p[i].ahead].pos; p[i].step=p[i+p[i].ahead].step+1; } } scanf("%d",&m); int x,y; for(int cas=1; cas<=m; ++cas) { scanf("%d",&op); if(op==1) { scanf("%d",&x); int ans=0; //一个块一个块的跳 while(p[x].Next!=0) { ans+=p[x].step; x=p[x].pos; } ans+=p[x].step; printf("%d ",ans); } else if(op==2)//更新 { scanf("%d%d",&x,&y); p[x].ahead=y; //更新的话,只更新在同一块内的 int l=(block[x]-1)*temp; for(int i=x; i>=l; i--) { if(block[i+p[i].ahead]!=block[i]) { p[i].Next=block[i+p[i].ahead]; p[i].pos=i+p[i].ahead; p[i].step=1; } else { p[i].Next=p[i+p[i].ahead].Next; p[i].pos=p[i+p[i].ahead].pos; p[i].step=p[i+p[i].ahead].step+1; } } } } return 0; }