bzoj:2002: [Hnoi2010]Bounce 弹飞绵羊
Description
某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
Input
第一行包含一个整数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
Output
对于每个i=1的情况,你都要输出一个需要的步数,占一行。
Sample Input
4
1 2 1 1
3
1 1
2 1 1
1 1
1 2 1 1
3
1 1
2 1 1
1 1
Sample Output
2
3
3
LCT……连模板都不算
#include<cstdio> #include<cstring> #include<algorithm> #define MN 200001 using namespace std; int p,ca,f; inline int read(){ p=0;ca=getchar(); while(ca<'0'||ca>'9') ca=getchar(); while(ca>='0'&&ca<='9') p=p*10+ca-48,ca=getchar(); return p; } struct na{ int y,ne; }b[MN*2]; int fa[MN],n,m,x,y,ch[MN][2],top,st[MN],key[MN],s[MN]; inline int max(int a,int b){return a>b?a:b;} inline bool isroot(int x){ return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; } inline void pd(int x){ } inline void up(int x){ s[x]=s[ch[x][0]]+s[ch[x][1]]+1; } inline void rot(int x){ int y=fa[x],kind=ch[y][1]==x; if(!isroot(y)) ch[fa[y]][ch[fa[y]][1]==y]=x; fa[x]=fa[y]; fa[y]=x; ch[y][kind]=ch[x][!kind]; fa[ch[y][kind]]=y; ch[x][!kind]=y; up(y);up(x); } inline void splay(int x){ register int i;top=1;st[1]=x; for (i=x;!isroot(i);i=fa[i]) st[++top]=fa[i]; for (i=top;i;i--) up(st[i]); while(!isroot(x)){ if (isroot(fa[x])) rot(x);else if ((ch[fa[fa[x]]][1]==fa[x])==(ch[fa[x]][1]==x)) rot(fa[x]),rot(x);else rot(x),rot(x); } } inline void acc(int u){ int x=0; while(u){ splay(u); ch[u][1]=x; u=fa[x=u]; } } inline void re(int x){ acc(x);splay(x); } inline void in(int x,int y){ if (y>n) return; re(x);re(y); ch[y][1]=x;fa[x]=y; } inline void del(int x,int y){ re(x);ch[x][0]=fa[ch[x][0]]=0; } inline void qu(int x){ acc(x);splay(x); printf("%d\n",s[x]); } int o; int main(){ register int i; n=read(); for (i=1;i<=n;i++) key[i]=read(),in(i,i+key[i]); m=read(); while(m--){ o=read(); int x,y,z;x=read();x++; if (o==1) qu(x);else if (o==2) del(x,x+key[x]),key[x]=read(),in(x,x+key[x]); } }