分块,每个点处理他跳到下一块时跳到哪个点,需要多少步
询问时一个一个块跳
修改时修改整个块的信息
code:
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 210000;
int id[maxn],s[maxn],_to[maxn],g[maxn];
int n,m,N;
int main()
{
scanf("%d",&n); N=sqrt(n);
for(int i=0;i<n;i++)
{
id[i]=i/N+1;
scanf("%d",&_to[i]);
_to[i]=min(i+_to[i],n);
}
id[n]=id[n-1]+1;
for(int i=n-1;i>=1;i--)
{
if(id[_to[i]]==id[i])
{
s[i]=s[_to[i]]+1;
g[i]=g[_to[i]];
}
else
{
s[i]=1;
g[i]=_to[i];
}
}
scanf("%d",&m);
while(m--)
{
int x,y,c;
scanf("%d",&c);
if(c==1)
{
scanf("%d",&x);
int ret=0;
while(x!=n)
{
ret+=s[x];
x=g[x];
}
printf("%d\n",ret);
}
else
{
scanf("%d%d",&x,&y);
_to[x]=min(n,x+y);
for(int i=x;id[i]==id[x];i--)
{
if(id[_to[i]]==id[i])
{
s[i]=s[_to[i]]+1;
g[i]=g[_to[i]];
}
else
{
s[i]=1;
g[i]=_to[i];
}
}
}
}
return 0;
}