某天,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的情况,你都要输出一个需要的步数,占一行。
ac代码
/************************************************************** Problem: 2002 User: kxh1995 Language: C++ Result: Accepted Time:1912 ms Memory:6280 kb ****************************************************************/ #include<stdio.h> #include<string.h> struct LCT { int bef[200050],pre[200050],next[200050][2],sum[200050],key[200050]; void init() { memset(pre,0,sizeof(pre)); memset(next,0,sizeof(next)); } void pushup(int x) { sum[x]=key[x]+sum[next[x][1]]+sum[next[x][0]]; } void rotate(int x,int kind) { int y,z; y=pre[x]; z=pre[y]; next[y][!kind]=next[x][kind]; pre[next[x][kind]]=y; next[z][next[z][1]==y]=x; pre[x]=z; next[x][kind]=y; pre[y]=x; pushup(y); } void splay(int x) { int rt; for(rt=x;pre[rt];rt=pre[rt]); if(x!=rt) { bef[x]=bef[rt]; bef[rt]=0; while(pre[x]) { if(next[pre[x]][0]==x) { rotate(x,1); } else rotate(x,0); } pushup(x); } } void access(int x) { int fa; for(fa=0;x;x=bef[x]) { splay(x); pre[next[x][1]]=0; bef[next[x][1]]=x; next[x][1]=fa; pre[fa]=x; bef[fa]=0; fa=x; pushup(x); } } int query(int x) { access(x); splay(x); // while(next[x][0]) // x=next[x][0]; return sum[next[x][0]]; } void cut(int x) { access(x); splay(x); bef[next[x][0]]=bef[x]; bef[x]=0; pre[next[x][0]]=0; next[x][0]=0; } void join(int x,int y) { if(y==0) cut(x); else { int tmp; access(y); splay(y); for(tmp=x;pre[tmp];tmp=pre[tmp]); if(tmp!=y) { cut(x); bef[x]=y; } } } }lct; int a[200020]; int main() { int n; while(scanf("%d",&n)!=EOF) { int i; lct.init(); for(i=1;i<=n;i++) { scanf("%d",&a[i]); if(a[i]+i>n) lct.bef[i]=0; else lct.bef[i]=a[i]+i; lct.key[i]=lct.sum[i]=1; } int m; scanf("%d",&m); while(m--) { int op; scanf("%d",&op); if(op==1) { int x; scanf("%d",&x); printf("%d\n",lct.query(x+1)+1); } else { int x,y; scanf("%d%d",&x,&y); x++; a[x]=y; if(x+y>n) //lct.bef[x]=0; y=0; else //lct.join(x,y+x); y=y+x; lct.join(x,y); } } } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
BZOJ 题目2002: [Hnoi2010]Bounce 弹飞绵羊(link cut tree)
原文:http://blog.csdn.net/yu_ch_sh/article/details/47732997