2002: [Hnoi2010]Bounce 弹飞绵羊

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 9071  Solved: 4652
[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

Sample Output

2
3

HINT

 

Source

 

[Submit][Status][Discuss]

将跳转看成边的关系,易知这些转移边形成一棵树。如果以“弹出去”这个状态为根节点,从一个点出发的步数可以转换为深度,或者说是从根节点到这个点的距离。改变一个点的系数,可以视为改变一个点的父节点,但是其子树不会受到影响。显然是个LCT模板题,第一次写还有些许不懂,大体是从这位前辈的blog里学的。

 VAR
n : longint;
m : longint;
siz : array[-..] of longint;
fat : array[-..] of longint;
rot : array[-..] of boolean;
son : array[-..,..] of longint; PROCEDURE update(t : longint);
begin
siz[t]:=siz[son[t,]]+siz[son[t,]]+;
end; PROCEDURE ltrotate(x : longint);
var
y : longint;
begin
y:=son[x,];
son[x,]:=son[y,];
fat[son[x,]]:=x;
son[y,]:=x;
if x=son[fat[x],] then
son[fat[x],]:=y
else if x=son[fat[x],] then
son[fat[x],]:=y;
fat[y]:=fat[x];
fat[x]:=y;
rot[y]:=rot[x] xor rot[y];
rot[x]:=rot[x] xor rot[y];
update(x);
update(y);
end; PROCEDURE rtrotate(x : longint);
var
y : longint;
begin
y:=son[x,];
son[x,]:=son[y,];
fat[son[x,]]:=x;
son[y,]:=x;
if x=son[fat[x],] then
son[fat[x],]:=y
else if x=son[fat[x],] then
son[fat[x],]:=y;
fat[y]:=fat[x];
fat[x]:=y;
rot[y]:=rot[x] xor rot[y];
rot[x]:=rot[x] xor rot[y];
update(x);
update(y);
end; PROCEDURE splay(x : longint);
begin
while not rot[x] do
if x=son[fat[x],] then
ltrotate(fat[x])
else
rtrotate(fat[x]);
end; PROCEDURE access(x : longint);
var
y : longint;
begin
splay(x);
while fat[x]<> do
begin
y:=fat[x];
splay(y);
rot[son[y,]]:=true;
rot[x]:=false;
son[y,]:=x;
update(y);
splay(x);
end;
end; PROCEDURE main;
var
i, x, y, z : longint;
begin
read(n); for i:= to n do
begin
read(fat[i]);
fat[i]:=fat[i]+i;
if fat[i]>n then
fat[i]:=n+;
end; for i:= to n+ do
begin
siz[i]:=;
rot[i]:=true;
end; read(m); for i:= to m do
begin
read(x);
if x= then
begin
read(y);
inc(y);
access(y);
writeln(siz[son[y,]]);
end
else
begin
read(y,z);
inc(y);
splay(y);
fat[son[y,]]:=fat[y];
rot[son[y,]]:=true;
son[y,]:=;
siz[y]:=siz[son[y,]]+;
fat[y]:=y+z;
if fat[y]>n then
fat[y]:=n+;
end;
end;
end; BEGIN
main;
END.
 #include <bits/stdc++.h>

 #define fread_siz 1024

 inline int get_c(void)
{
static char buf[fread_siz];
static char *head = buf + fread_siz;
static char *tail = buf + fread_siz; if (head == tail)
fread(head = buf, , fread_siz, stdin); return *head++;
} inline int get_i(void)
{
register int ret = ;
register int neg = false;
register int bit = get_c(); for (; bit < ; bit = get_c())
if (bit == '-')neg ^= true; for (; bit > ; bit = get_c())
ret = ret * + bit - ; return neg ? -ret : ret;
} template <class T>
inline T min(T a, T b)
{
return a < b ? a : b;
} const int N = ; int n, m;
int root[N];
int lson[N];
int rson[N];
int size[N];
int father[N]; inline void update(int t)
{
size[t] = size[lson[t]] + size[rson[t]] + ;
} inline void rotateLeft(int t)
{
int r = rson[t];
rson[t] = lson[r];
father[rson[t]] = t;
lson[r] = t;
if (t == lson[father[t]])
lson[father[t]] = r;
else if (t == rson[father[t]])
rson[father[t]] = r;
father[r] = father[t];
father[t] = r;
update(t);
update(r);
root[r] ^= root[t];
root[t] ^= root[r];
} inline void rotateRight(int t)
{
int l = lson[t];
lson[t] = rson[l];
father[lson[t]] = t;
rson[l] = t;
if (t == lson[father[t]])
lson[father[t]] = l;
else if (t == rson[father[t]])
rson[father[t]] = l;
father[l] = father[t];
father[t] = l;
update(t);
update(l);
root[l] ^= root[t];
root[t] ^= root[l];
} inline void splay(int t)
{
while (!root[t])
{
if (t == lson[father[t]])
rotateRight(father[t]);
else
rotateLeft(father[t]);
}
} inline void access(int t)
{
splay(t); while (father[t])
{
int f = father[t];
splay(f);
root[rson[f]] = ;
root[t] = ;
rson[f] = t;
update(f);
splay(t);
}
} inline void cut(int t)
{
splay(t);
root[lson[t]] = ;
father[lson[t]] = father[t];
lson[t] = ;
update(t);
} signed main(void)
{
n = get_i(); for (int i = ; i <= n; ++i)
father[i] = min(get_i() + i, n + ); for (int i = ; i <= n + ; ++i)
size[i] = root[i] = ; m = get_i(); for (int i = ; i <= m; ++i)
{
int x = get_i(), y, z;
if (x == )
{
y = get_i() + ; access(y);
printf("%d\n", size[lson[y]]);
}
else
{
y = get_i() + ; z = get_i();
cut(y); father[y] = min(n + , y + z);
}
}
}

@Author: YouSiki

BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊的更多相关文章

  1. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 分块

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...

  2. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...

  3. bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 動態樹

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 4055  Solved: 2172[Submi ...

  4. bzoj 2002 : [Hnoi2010]Bounce 弹飞绵羊 (LCT)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 题面: 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: ...

  5. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2843  Solved: 1519[Submi ...

  6. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 【分块】

    任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 ...

  7. BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊:分块

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 题意: 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆 ...

  8. 【刷题】BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...

  9. 洛谷 P3203 BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊

    题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系 ...

随机推荐

  1. Canvas的width,height 和 样式中Canvas的width,height

    控制Canvas的大小,有两种方式: 1:直接设置Canvas标签上的书width,height属性值; 2:通过Css设置Canvas的width,height; 这两种方式,区别是很大的. 1:C ...

  2. css3 transition属性

    最近打算学习css3知识,觉得css3写出来的效果好炫好酷,之前一直想要学习来着.可能之前的决心,毅力,耐心不够,所以想要重整起来,放下浮躁的心态,一步一个脚印,踏踏实实的来学习. 首先学习的是css ...

  3. 关于从Activity A跳转到Activity B ,其中Activity A中有一个VideoView,Activity B中有一个MediaPlayer。

    两个不同的视频的跳转, 前面我是在onStop()方法中销毁VideoView(因为MediaPlayer是全局共用的,而VideoView内包含MediaPlayer),但是每次进入Activity ...

  4. 安装cocoapods遇到两大坑-Ruby版本升级和Podfile的配置

    今天安装cocoapods #移除原有ruby源 $ gem sources --remove https://rubygems.org/ #使用可用的淘宝网 $ gem sources -a htt ...

  5. MYSQL基础操作之数据约束与关联查询

    一.MYSQL约束 1.默认值约束,当字段没有插入值的时候,mysql自动给该字段分配默认值. 默认值的字段允许为空. 对默认值字段也可以插入null. CREATE TABLE STUDENT( I ...

  6. yii2 modal弹窗之ActiveForm ajax表单异步验证

    作者:白狼 出处:http://www.manks.top/yii2_modal_activeform_ajax.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位 ...

  7. MySQL Performance-Schema(二) 理论篇

    MySQL Performance-Schema中总共包含52个表,主要分为几类:Setup表,Instance表,Wait Event表,Stage Event表Statement Event表,C ...

  8. SecondaryNameNode的工作流程

    SecondaryNameNode是用来合并fsimage和edits文件来更新NameNode和metadata的. 其工作流程为: 1.secondary通知namenode切换edits文件 2 ...

  9. RemodelanyWhere11.0.2673版本下载

    百度云盘链接:http://pan.baidu.com/s/1geL5lez 密码:hisq 原文转载至:http://blog.sun0816.com/13623.html

  10. 使用fdisk给新增加硬盘分区

    1.使用fdisk创建6个分区[1P+1E(5L)]   //dev/sdb1 /dev/sdb5 /dev/sdb6 /dev/sdb7 /dev/sdb8 /deb/sdb9 [root@serv ...