【HNOI2010】【BZOJ2002】Bounce 弹飞绵羊

原创 2015年08月16日 15:08:14

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

HINT

Source

Splay 启发式合并

直接从i向i+k[i]link一下就行了.
每次修改k记得要先cut原边再加入新边
询问就是维护一下子树size
把弹飞的点都link到n+1上.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 200100
using namespace std;
int n,m;
int k[MAXN];
int sta[MAXN],top;
int opt,u,v;
struct splay
{
    int fa,ch[2],size;
    bool rev;
}tree[MAXN];
inline void in(int &x)
{
    char ch=getchar();int flag=1;x=0;
    while (!(ch>='0'&&ch<='9')) flag=ch=='-'?-1:1,ch=getchar();
    while (ch>='0'&&ch<='9')    x=x*10+ch-'0',ch=getchar();
}
inline bool is_root(int x)
{
    return tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x;
}
inline void push_down(int x)
{
    if (tree[x].rev)
    {
        tree[x].rev^=1;tree[tree[x].ch[0]].rev^=1;tree[tree[x].ch[1]].rev^=1;
        swap(tree[x].ch[0],tree[x].ch[1]);
    }
}
inline void push_up(int x)
{
    tree[x].size=tree[tree[x].ch[0]].size+tree[tree[x].ch[1]].size+1;
}
inline void rot(int x)
{
    int y=tree[x].fa,z=tree[y].fa,l,r;
    l=(tree[y].ch[1]==x);r=l^1;
    if (!is_root(y))    tree[z].ch[tree[z].ch[1]==y]=x;
    tree[tree[x].ch[r]].fa=y;tree[y].fa=x;tree[x].fa=z;
    tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y;
    push_up(x);push_up(y);
}
inline void Splay(int x)
{
    sta[++top]=x;
    for (int i=x;!is_root(i);i=tree[i].fa)  sta[++top]=tree[i].fa;
    while (top) push_down(sta[top--]);
    while (!is_root(x))
    {
        int y=tree[x].fa,z=tree[y].fa;
        if (!is_root(y))
        {
            if (tree[y].ch[0]==x^tree[z].ch[0]==y)  rot(x);
            else    rot(y);
        }
        rot(x);
    }
}
inline void access(int x)
{
    for (int i=0;x;i=x,x=tree[x].fa)    Splay(x),tree[x].ch[1]=i,push_up(x);
}
inline void make_root(int x)
{
    access(x);Splay(x);tree[x].rev^=1;
}
inline void link(int x,int y)
{
    Splay(x);tree[x].fa=y;
}
inline void cut(int x,int y)
{
    make_root(x);access(y);Splay(y);tree[y].ch[0]=tree[x].fa=0;
}
inline int find(int x)
{
    access(x);Splay(x);
    int ret=x;
    while (tree[ret].ch[0]) ret=tree[ret].ch[0];
    return ret;
}
int main()
{
    in(n);tree[n+1].size=1;
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&k[i]);
        tree[i].size=1;tree[i].fa=min(i+k[i],n+1);
    }
    in(m);
    while (m--)
    {
        in(opt);
        if (opt==1)
        {
            in(u);u++;make_root(n+1);
            access(u);Splay(u);
            printf("%d\n",tree[tree[u].ch[0]].size);
        }
        if (opt==2)
        {
            in(u);in(v);u++;
            cut(u,min(u+k[u],n+1));k[u]=v;link(u,min(u+k[u],n+1));
        }
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

bzoj2002 弹飞绵羊

分为sqrt(n)左右块,next[i]记录从i跳出当前块的位置,time[i]记录相应次数,up返回当前点所在块最大值,low返回最小值。提前把low、up存起来似乎更快。。。开始先把next、ti...
  • sdlyyxy
  • sdlyyxy
  • 2015年02月25日 20:18
  • 1037

【HNOI 2010】Bounce 弹飞绵羊 分块

BZOJ Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个...
  • Qantun_Mechanics
  • Qantun_Mechanics
  • 2016年09月30日 17:22
  • 1260

animate.css源码分析--bounce(弹跳效果)

animate.css是一个不错CSS3预设动画库,是很好的CSS3动画学习资源,下面来剖析下bounce效果的实现原理,在此基础上实现自己的CSS动画。 先从animate.css把bounce效...
  • zhaozjc112
  • zhaozjc112
  • 2016年11月09日 20:09
  • 2482

【bzoj2002】【Hnoi2010】【Bounce 弹飞绵羊】【lct】

题目大意某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数...
  • chunkitlau
  • chunkitlau
  • 2017年05月12日 21:25
  • 80

BZOJ2002——[Hnoi2010]Bounce 弹飞绵羊

1、题目大意:就是给一个动态的森林求size域 2、分析: 这个就是一个动态树问题,对于每一个位置i有i+ki这个父亲, 于是这就是一个森林了,然后对于每一个修改直接lct维护就好,询问就是i到最外...
  • qzh_1430586275
  • qzh_1430586275
  • 2016年05月17日 08:21
  • 270

初识lct——洛谷p3203 bzoj2002 [HNOI2010]BOUNCE 弹飞绵羊

题目大意:现在有n个装置,每个装置会弹到一个地方(编号一定在它之后),也可能直接弹了出去,动态修改会弹到的地方,和动态查询从一个装置出发多少次会被弹出去。...
  • Cold_Chair
  • Cold_Chair
  • 2017年06月03日 19:01
  • 226

【BZOJ 2002】 [Hnoi2010]Bounce 弹飞绵羊

【BZOJ 2002】 [Hnoi2010]Bounce 弹飞绵羊 LCT模板题~
  • Regina8023
  • Regina8023
  • 2014年12月12日 15:10
  • 801

【LCT】BZOJ2002(Hnoi2010)[Bounce 弹飞绵羊]题解

BZOJ2002题解。
  • zzkksunboy
  • zzkksunboy
  • 2017年05月17日 19:39
  • 673

bzoj2002: [Hnoi2010]Bounce 弹飞绵羊

2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 10629  Solved: 5476 ...
  • Brian551
  • Brian551
  • 2017年06月20日 21:20
  • 118

bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊(分块)

2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 10761  Solved: 5542 [Su...
  • Jaihk662
  • Jaihk662
  • 2017年07月12日 16:49
  • 228
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【HNOI2010】【BZOJ2002】Bounce 弹飞绵羊
举报原因:
原因补充:

(最多只允许输入30个字)