話說我是冒着巨大的風險A這道題的(xc說不讓上其他oj)。
這題其實很簡單,每個點如果他能往後跳,那就只能跳到唯一的一個,這顯然是跟森林,用lct就好,維護下size。
代碼突然變短
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define lc c[x][0]
#define rc c[x][1]
using namespace std;
const int N=200000+5;
int c[N][2],s[N],f[N],r[N],k[N];
int n,m,flag,x,y;
void R(int &x){
int t=0; char ch;
for (ch=getchar();!('0'<=ch&&ch<='9');ch=getchar());
for (;('0'<=ch&&ch<='9');ch=getchar()) t=t*10+ch-'0';
x=t;
}
bool wh(int x){
return x==c[f[x]][1];
}
bool nroot(int x){
return x==c[f[x]][0]||x==c[f[x]][1];
}
void update(int x){
s[x]=1+s[lc]+s[rc];
}
void rotate(int x){
int y=f[x],z=f[y],k=wh(x),w=c[x][1^k];
if (nroot(y)) c[z][wh(y)]=x; f[x]=z;
c[y][k]=w; if (w) f[w]=y;
c[x][1^k]=y; f[y]=x;
update(y); update(x);
}
void splay(int x){
for (;nroot(x);rotate(x))
if (nroot(f[x]))
rotate(wh(x)==wh(f[x])?f[x]:x);
}
void access(int x){
for (int y=0;x;x=f[y=x])
splay(x),rc=y,update(x);
}
int main(){
//freopen("bzoj2002.in","r",stdin);
//freopen("bzoj2002.out","w",stdout);
R(n);
fo(i,1,n){
R(k[i]);
if (k[i]+i<=n) f[i]=k[i]+i;
s[i]=1;
}
R(m);
while (m--){
R(flag); R(x); x++;
if (flag==1){
access(x); splay(x); printf("%d\n",s[x]);
}
else{
R(y);
access(x); splay(x);
lc=f[lc]=0;
if (y+x<=n) f[x]=x+y;
update(x);
}
}
return 0;
}