【链接】
bzoj2002
【解题报告】
听说这是裸LCT啊,不会啊,只能用分块大法了,我太弱了QAQ
看题目n挺小的,直接分块大法就好了。
#include<cstdio>
#include<cmath>
#define Block(x) ((x)-1)/S+1
#define min(x,y) ((x)<(y))?(x):(y)
using namespace std;
const int maxn=200005;
int n,m,S,a[maxn],nxt[maxn],p[maxn];
inline char nc()
{
static char buf[100000],*l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
if (l==r) return EOF; return *l++;
}
inline int Read()
{
int res=0; char ch=nc();
while (ch<'0'||ch>'9') ch=nc();
while (ch>='0'&&ch<='9') res=(res<<3)+(res<<1)+ch-48,ch=nc();
return res;
}
void Updata(int x)
{
int s=Block(x),t=Block(x+a[x]);
if (t>s||x+a[x]>n) nxt[x]=min(x+a[x],n+1),p[x]=1;
else nxt[x]=nxt[x+a[x]],p[x]=p[x+a[x]]+1;
}
int Query(int x) {int sum=0; while (x<=n) sum+=p[x],x=nxt[x]; return sum;}
int main()
{
freopen("2002.in","r",stdin);
freopen("2002.out","w",stdout);
n=Read(); S=sqrt(n);
for (int i=1; i<=n; i++) a[i]=Read();
for (int i=n; i; i--) Updata(i);
m=Read();
for (int i=1; i<=m; i++)
{
int z=Read(),x=Read()+1;
if (z==1) printf("%d\n",Query(x));
else{a[x]=Read(); for (int i=x,s=(Block(x)-1)*S+1; i>=s; i--) Updata(i);}
}
return 0;
}