bzoj:2002: [Hnoi2010]Bounce 弹飞绵羊

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

Sample Output

2
3
 
LCT……连模板都不算
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MN 200001
using namespace std;

int p,ca,f;
inline int read(){
    p=0;ca=getchar();
    while(ca<'0'||ca>'9') ca=getchar();
    while(ca>='0'&&ca<='9') p=p*10+ca-48,ca=getchar();
    return p;
}
struct na{
    int y,ne;
}b[MN*2];
int fa[MN],n,m,x,y,ch[MN][2],top,st[MN],key[MN],s[MN];
inline int max(int a,int b){return a>b?a:b;}
inline bool isroot(int x){
    return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
inline void pd(int x){
}
inline void up(int x){
    s[x]=s[ch[x][0]]+s[ch[x][1]]+1;
}
inline void rot(int x){
    int y=fa[x],kind=ch[y][1]==x;
    if(!isroot(y)) ch[fa[y]][ch[fa[y]][1]==y]=x;
    fa[x]=fa[y];
    fa[y]=x;
    ch[y][kind]=ch[x][!kind];
    fa[ch[y][kind]]=y;
    ch[x][!kind]=y;
    up(y);up(x);
}
inline void splay(int x){
    register int i;top=1;st[1]=x;
    for (i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
    for (i=top;i;i--) up(st[i]);
    while(!isroot(x)){
        if (isroot(fa[x])) rot(x);else
        if ((ch[fa[fa[x]]][1]==fa[x])==(ch[fa[x]][1]==x)) rot(fa[x]),rot(x);else rot(x),rot(x);
    }
}
inline void acc(int u){
    int x=0;
    while(u){
        splay(u);
        ch[u][1]=x;
        u=fa[x=u];
    }
}
inline void re(int x){
    acc(x);splay(x);
}
inline void in(int x,int y){
    if (y>n) return;
    re(x);re(y);
    ch[y][1]=x;fa[x]=y;
}
inline void del(int x,int y){
    re(x);ch[x][0]=fa[ch[x][0]]=0;
}
inline void qu(int x){
    acc(x);splay(x);
    printf("%d
",s[x]);
}
int o;
int main(){
    register int i;
    n=read();
    for (i=1;i<=n;i++) key[i]=read(),in(i,i+key[i]);
    m=read();
    while(m--){
        o=read();
        int x,y,z;x=read();x++;
        if (o==1) qu(x);else
        if (o==2) del(x,x+key[x]),key[x]=read(),in(x,x+key[x]);
    }
}
原文地址:https://www.cnblogs.com/Enceladus/p/5239986.html