分块+线性DP
维护从某个点出发跳出这个块会跳到哪,需要几步即可
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
#include"cmath"
using namespace std;
const int MAXN=2e5+5;
const int MAXM=505;
int n,m,siz;
int a[MAXN],v[MAXN],l[MAXN],r[MAXN],id[MAXN],g[MAXN];
int blk[MAXM];
int cqr(int x)
{
int sum=0,ct=x;
while(ct<n) sum+=g[ct],ct=v[ct];
return sum;
}
void cchg(int x,int val)
{
a[x]=val;
for(int i=x;i>=l[x];--i){
v[i]=min(a[i]+i,n);
if(v[i]>r[i]) g[i]=1;
else g[i]=g[v[i]]+1,v[i]=v[v[i]];
}return;
}
int main()
{
scanf("%d",&n);siz=sqrt(n);v[n]=n;
for(int i=0;i<n;++i){
scanf("%d",&a[i]);
id[i]=i/siz;
l[i]=id[i]*siz;
r[i]=min((id[i]+1)*siz-1,n-1);
}for(int i=n-1;i>=0;--i){
v[i]=min(a[i]+i,n);
if(v[i]>r[i]) g[i]=1;
else g[i]=g[v[i]]+1,v[i]=v[v[i]];
}scanf("%d",&m);
while(m--){
int c,x,y;scanf("%d",&c);
if(c==1) scanf("%d",&x),printf("%d\n",cqr(x));
else scanf("%d%d",&x,&y),cchg(x,y);
}return 0;
}
原文:https://www.cnblogs.com/AH2002/p/10034409.html