弹飞绵羊

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的情况,你都要输出一个需要的步数,占一行。

有向边的树写起来似乎还简单点。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 200005
int ch[MAXN][2],fa[MAXN],sz[MAXN],arr[MAXN];
bool rev[MAXN],tp[MAXN];
int n,m;
void getint(int &num)
{
    num=0;
    char c;
    int flag=1;
    while((c=getchar())&&!isdigit(c))if(c=='-')flag=-1;
    while(isdigit(c)){num=num*10+c-48;c=getchar();}
}
void pushdown(int r)
{
}
void pushup(int r)
{
    sz[r]=sz[ch[r][0]]+sz[ch[r][1]]+1;
}
void init()
{
    for(int i=1;i<=n;i++)
        {sz[i]=1;
         tp[i]=1;
        }
}
void rot(int x)
{
    if(x==0||tp[x]==1)return;
    int y=fa[x],z=fa[y];
    pushdown(y),pushdown(x);
    bool flag=(ch[y][1]==x);
    ch[y][flag]=ch[x][!flag];
    if(ch[y][flag])fa[ch[y][flag]]=y;
    ch[x][!flag]=y;
    fa[y]=x;
    fa[x]=z;
    if(tp[y]==0)ch[z][ch[z][1]==y]=x;
    tp[x]=tp[y];
    tp[y]=0;
    sz[x]=sz[y];
    pushup(y);
}
void splay(int x)
{
    pushdown(x);
    pushup(x);
    if(tp[x]==1)return;
    for(;tp[x]==0;rot(x))
    {
        int y=fa[x];
        if(tp[y]==0)
        {
            int z=fa[y];
            rot(((ch[z][1]==y)==(ch[y][1]==x))?y:x);
        }
    }
    pushdown(x);
    pushup(x);
}
int access(int x)
{
 
    int last=0;
    while(x)
    {
        splay(x);
        if(ch[x][1])tp[ch[x][1]]=1;
        ch[x][1]=last;
        tp[last]=0;
        last=x;
        pushup(x);
        x=fa[x];
    }
}
void change(int u,int v)
{
    if(v>n)v=0;
    splay(u);
    if(ch[u][0])
        {fa[ch[u][0]]=fa[u];
         tp[ch[u][0]]=1;
        }
    ch[u][0]=0;
    pushup(u);
    fa[u]=v;
}
void link(int u,int v)
{
    if(v)
    {
    fa[u]=v;
    pushup(v);
    tp[u]=1;
    }
}
int main()
{
    getint(n);
 
    init();
    for(int i=1;i<=n;i++)
    {getint(arr[i]);
      link(i,(i+arr[i]>n)?0:(i+arr[i]));
    }
    getint(m);
    int opt,t1,t2;
    for(int i=1;i<=m;i++)
    {
       getint(opt);
       getint(t1);
       t1++;
       if(opt==1)
        {access(t1);
         splay(t1);
         printf("%d
",sz[t1]);
        }
       else
       {
         getint(t2);
         change(t1,t1+t2);
       }
}
}
原文地址:https://www.cnblogs.com/hefenghhhh/p/5028880.html