题意:
修改一个数
从i开始每次到$a_i$,超过n需要几次
分块跑的比LCT都快......
每个块维护块内每个点几步跳出块并跳到哪个位置
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int N=2e5+5; inline int read(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f; }int n,a[N],Q,op,x; struct Block{int block,m,pos[N],f[N],g[N];void ini(){block=sqrt(n); m=(n-1)/block+1;for(int i=1;i<=n;i++) pos[i]=(i-1)/block+1;//for(int i=1;i<=m;i++) l[i]=(i-1)*block+1,r[i]=i*block;//r[m]=n;for(int i=n;i>=1;i--){if(pos[i]==pos[a[i]]) f[i]=f[a[i]]+1,g[i]=g[a[i]];else f[i]=1,g[i]=a[i];}}int que(int x){int re=0;for(int i=x;i<=n;i=g[i]) re+=f[i];return re;}void cha(int x,int v){a[x]=x+v; int l=(pos[x]-1)*block+1;for(int i=x;i>=l;i--){if(pos[i]==pos[a[i]]) f[i]=f[a[i]]+1,g[i]=g[a[i]];else f[i]=1,g[i]=a[i];}} }B; int main(){freopen("in","r",stdin);n=read();for(int i=1;i<=n;i++) a[i]=read()+i;B.ini();Q=read();while(Q--){op=read();x=read()+1;if(op==1) printf("%d\n",B.que(x));else B.cha(x,read());} }