2002: [Hnoi2010]Bounce 弹飞绵羊
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 5421 Solved: 2863
[ Submit][ Status][ Discuss]
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
HINT
Source
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);
}
}
}
}