某天,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的情況,你都要輸出一個需要的步數,占一行。
Splay 啟發式合並
ac代碼
/************************************************************** Problem: 2002 User: kxh1995 Language: C++ Result: Accepted Time:1912 ms Memory:6280 kb ****************************************************************/ #include#include 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); } } } }
版權聲明:本文為博主原創文章,未經博主允許不得轉載。