2002: [Hnoi2010]Bounce 弹飞绵羊
题目描述
某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
解题思路
这是一道比较明显的动态树问题,初始时将
i
和
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=200005;
struct jz{
int s,son[2],f,flg;
}a[maxn];
int n,Q,k[maxn],top,stack[maxn];
inline int _read(){
int num=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') num=num*10+ch-48,ch=getchar();
return num;
}
void pushup(int x){a[x].s=a[a[x].son[0]].s+a[a[x].son[1]].s+1;}
void tag(int x){swap(a[x].son[0],a[x].son[1]);a[x].flg^=1;}
void pushdown(int x){
if (!a[x].flg) return;
if (a[x].son[1]) tag(a[x].son[1]);
if (a[x].son[0]) tag(a[x].son[0]);
a[x].flg=0;
}
bool is_ro(int x){return x!=a[a[x].f].son[1]&&x!=a[a[x].f].son[0];}
void rotate(int x){
int fa=a[x].f,d=x==a[fa].son[0];
if (!is_ro(fa)) a[a[fa].f].son[fa==a[a[fa].f].son[1]]=x;
a[fa].son[d^1]=a[x].son[d];a[a[x].son[d]].f=fa;a[x].son[d]=fa;
pushup(fa);pushup(x);a[x].f=a[fa].f;a[fa].f=x;
}
void splay(int x){
stack[++top]=x;
for (int i=x;!is_ro(i);i=a[i].f) stack[++top]=a[i].f;
while (top) pushdown(stack[top--]);
while (!is_ro(x)){
int fa=a[x].f;
if (!is_ro(fa)){
int d1=fa==a[a[fa].f].son[1],d2=x==a[fa].son[1];
if (d1==d2) rotate(fa);else rotate(x);
}
rotate(x);
}
}
void Access(int x){
int lst=0;
while(x){
splay(x);a[x].son[1]=lst;pushup(x);
lst=x;x=a[x].f;
}
}
void make_ro(int x){Access(x);splay(x);tag(x);}
void link(int x,int y){make_ro(y);a[y].f=x;}
void cut(int x,int y){
make_ro(y);Access(x);splay(x);
a[y].f=a[x].son[0]=0;pushup(x);
}
int main(){
freopen("exam.in","r",stdin);
freopen("exam.out","w",stdout);
n=_read();
for (int i=1;i<=n+1;i++) a[i].s=1;
for (int i=1;i<=n;i++) k[i]=_read(),link(min(i+k[i],n+1),i);
Q=_read();
while (Q--){
int d=_read(),x=_read()+1,y;
if (d==1){
make_ro(n+1);Access(x);splay(x);
printf("%d\n",a[x].s-1);
}else cut(min(x+k[x],n+1),x),link(min(x+(k[x]=_read()),n+1),x);
}
return 0;
}