題目連結
據說是一道LCT模闆題 然而我并不會LCT,是以用分塊做法切了他 維護每個點跳出目前塊所需次數,及跳到下個塊的什麼位置就好了
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#define For(i,j,k) for(int i=j;i<=k;i++)
#define Forr(i,j,k) for(int i=j;i>=k;i--)
using namespace std;
const int N=200000+5;
int l[N],r[N],belong[N],st[N],pi[N];
int K[N];
inline int read(){
char c=getchar();
while(c<'0'||c>'9')c=getchar();
int x=c-'0';
c=getchar();
while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();}
return x;
}
int n,m,block,cnt;
int cal(int x){
int tmp=0;
while(1){
tmp+=st[x];
if(!pi[x])break;
x=pi[x];
}
return tmp;
}
int main(){
n=read();
For(i,1,n)K[i]=read();
block=int(sqrt(n));
if(n%block)cnt=n/block+1;
else cnt=n/block;
For(i,1,cnt){
l[i]=(i-1)*block+1;
r[i]=i*block;
}
r[cnt]=n;
For(i,1,n)belong[i]=(i-1)/block+1;
Forr(i,n,1){
if(i+K[i]>n)st[i]=1;
else if(belong[i]==belong[i+K[i]]){st[i]=st[i+K[i]]+1;pi[i]=pi[i+K[i]];}
else {st[i]=1;pi[i]=i+K[i];}
}
m=read();
int f,x,y;
For(i,1,m){
f=read();x=read();
x++;
if(f==1)cout<<cal(x)<<endl;
else{
y=read();
K[x]=y;
Forr(j,x,l[belong[x]]){
if(j+K[j]>n){st[j]=1;pi[j]=0;}
else if(belong[j]==belong[j+K[j]]){st[j]=st[j+K[j]]+1;pi[j]=pi[j+K[j]];}
else {st[j]=1;pi[j]=j+K[j];}
}
}
}
return 0;
}