2002: [Hnoi2010]Bounce 弹飞绵羊
Time Limit: 10 Sec Memory Limit: 259 MBDescription
某天,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
HINT
LCT入门题
#include<map> #include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define inf 1000000007 #define ll long long #define N 200010 inline int rd() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m; int nxt[N],c[N][2],fa[N],sz[N],st[N]; bool rev[N]; #define ls c[x][0] #define rs c[x][1] inline bool isrt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;} inline void pd(int x) { if(!rev[x]) return; rev[ls]^=1;rev[rs]^=1; swap(ls,rs);rev[x]=0; } inline void upd(int x){sz[x]=sz[ls]+sz[rs]+1;} void rot(int x) { int y=fa[x],z=fa[y],l,r; l=c[y][1]==x;r=l^1; if(!isrt(y)) c[z][c[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[c[x][r]]=y; c[y][l]=c[x][r];c[x][r]=y; upd(x);upd(y); } void splay(int x) { int tt=1,y,z;st[1]=x; for(int i=x;!isrt(i);i=fa[i]) st[++tt]=fa[i]; for(int i=tt;i;i--) pd(st[i]); while(!isrt(x)) { y=fa[x];z=fa[y]; if(!isrt(y)) { if(c[y][0]==x^c[z][0]==y) rot(x); else rot(y); } rot(x); } } void acc(int x) { int t=0; while(x) { splay(x); rs=t; t=x;x=fa[x]; } } void rever(int x) { acc(x);splay(x); rev[x]^=1; } void cut(int x,int y) { rever(x);acc(y); splay(y);c[y][0]=fa[x]=0; } void link(int x,int y) { rever(x);fa[x]=y; splay(x); } int main() { n=rd(); for(int i=1,x;i<=n;i++) { x=rd(); fa[i]=x+i;sz[i]=1; if(fa[i]>n+1) fa[i]=n+1; nxt[i]=fa[i]; } sz[n+1]=1; m=rd(); int op,x,y,t; while(m--) { op=rd(); if(op==1) { rever(n+1); x=rd()+1; acc(x);splay(x); printf("%d ",sz[ls]); } else { x=rd()+1;y=rd(); t=min(n+1,x+y); cut(x,nxt[x]);link(x,t);nxt[x]=t; } } return 0; }