Description
某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
【题目分析】
分块
【代码】
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,a[200001];
int L[501],R[501],T,cnt=0,q,op,x,y;
int step[200001],to[200001],bel[200001];
int read()
{
int ret=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9')
{
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9')
{
ret*=10;
ret+=ch-'0';
ch=getchar();
}
return f*ret;
}
void init()
{
n=read();
for (int i=1;i<=n;++i) a[i]=read();
T=sqrt(n);
for (int i=1;i<=n;i+=T)
{
cnt++;
L[cnt]=i;
R[cnt]=min(i+T-1,n);
}
R[cnt]=n;
for (int i=1;i<=cnt;++i)
for (int j=L[i];j<=R[i];++j)
bel[j]=i;
for (int i=cnt;i>=1;--i)
for (int j=R[i];j>=L[i];--j)
{
if (j+a[j]>R[i])
{
step[j]=1;
to[j]=j+a[j];
}
else
{
step[j]=1+step[j+a[j]];
to[j]=to[j+a[j]];
}
}
}
void query()
{
int ans=0;
x=read();x++;
while (x<=n)
{
ans+=step[x];
x=to[x];
}
printf("%d\n",ans);
}
void mod()
{
x=read();y=read();x++;
a[x]=y;
if (a[x]+x>R[bel[x]]) step[x]=1,to[x]=x+a[x];
else step[x]=step[x+a[x]]+1,to[x]=to[x+a[x]];
for(int i=x-1;i>=L[bel[x]];i--)
{
if (i+a[i]>R[bel[x]])
{
step[i]=1;
to[i]=i+a[i];
}
else
{
step[i]=1+step[i+a[i]];
to[i]=to[i+a[i]];
}
}
}
int main()
{
init();
q=read();
while (q--)
{
op=read();
if (op==1) query();
else mod();
}
}