块状链表,分块处理,先预处理每一个点跳到下一个块 跳到哪,步数。然后修改的时候,修该那一个块即可
#include<cstdio>
#include<cmath>int a[200006],n,m,b[200006],c[200006],dian[200006],l[200006],r[200006];int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int len,len1; len1=floor(sqrt(n)); len=n/len1; if(len1*len1!=n) len++; for(int i=1;i<=len;i++) { l[i]=(i-1)*len1+1; r[i]=i*len1; } r[len]=n; for(int i=1;i<=n;i++) dian[i]=(i-1)/len1+1; for(int i=len;i>0;i--) for(int j=r[i];j>=l[i];j--) { if(j+a[j]>r[i]) { b[j]=j+a[j]; c[j]=1; } else { b[j]=b[j+a[j]]; c[j]=c[j+a[j]]+1; } } scanf("%d",&m); for(int i=0;i<m;i++) { int a1,a2,a3; scanf("%d%d",&a1,&a2); a2++; if(a1==1) { int sum=0; for(int j=a2;j<=n;j=b[j]) sum+=c[j]; printf("%d\n",sum); } else { scanf("%d",&a3); a[a2]=a3; for(int j=a2;j>=l[dian[a2]];j--) { if(j+a[j]>r[dian[a2]]) { b[j]=j+a[j]; c[j]=1; } else { b[j]=b[j+a[j]]; c[j]=c[j+a[j]]+1; } } } } return 0;}