某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1,接下来一行有n个正整数,依次为那n个装置的初始弹力系数。第三行有一个正整数m,接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000
对于每个i=1的情况,你都要输出一个需要的步数,占一行。
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; int n,fa[200003],son[200003][3],next[200003],size[200003]; int rev[200003],st[200003],m; bool isroot(int x) { return son[fa[x]][0]!=x&&son[fa[x]][1]!=x; } void pushdown(int x) { if (rev[x]) { rev[son[x][0]]^=1; rev[son[x][1]]^=1; rev[x]^=1; swap(son[x][0],son[x][1]); } } void update(int x) { size[x]=size[son[x][1]]+size[son[x][0]]+1; } int get(int x) { return son[fa[x]][1]==x; } void rotate(int x) { int y=fa[x],z=fa[y],l,r; if(son[y][0]==x)l=0;else l=1;r=l^1; if(!isroot(y)) { if(son[z][0]==y)son[z][0]=x;else son[z][1]=x; } fa[x]=z;fa[y]=x;fa[son[x][r]]=y; son[y][l]=son[x][r];son[x][r]=y; update(y);update(x); } void splay(int x) { int top=0; st[++top]=x; for (int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i]; for (int i=top;i>0;i--) pushdown(st[i]); while(!isroot(x)) { int y=fa[x]; int z=fa[y]; if (!isroot(y)) if(son[y][0]==x^son[z][0]==y) rotate(x); else rotate(y); rotate(x); } } void access(int x) { int t=0; while (x) { splay(x); son[x][1]=t; t=x; x=fa[x]; } } void rever(int x) { access(x); splay(x); rev[x]^=1; } void cut(int x,int y) { rever(x); access(y); splay(y); son[y][0]=fa[x]=0; } void link(int x,int y) { rever(x); fa[x]=y; splay(x); } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { int x; scanf("%d",&x); fa[i]=x+i; size[i]=1; if (x+i>n+1) fa[i]=n+1; next[i]=fa[i]; } size[n+1]=1; scanf("%d",&m); for (int i=1;i<=m;i++) { int op;scanf("%d",&op); if (op==1) { rever(n+1); int x; scanf("%d",&x); x++; access(x); splay(x); printf("%d\n",size[son[x][0]]); } else { int x,y; scanf("%d%d",&x,&y); x++; int t=min(n+1,x+y); cut(x,next[x]); link(x,t); next[x]=t; } } }