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. HashMap 源码解析

    HashMap简介: HashMap在日常的开发中应用的非常之广泛,它是基于Hash表,实现了Map接口,以键值对(key-value)形式进行数据存储,HashMap在数据结构上使用的是数组+链表. ...

  2. xampp与Hbuilder、phpstorm配置

    1.xampp的安装就不用多说了,安装完按之后出现这个界面. 2.点击中间那个按钮,运行三个选项,全部正常之后是这样的,这样xampp就不用管了,但是要记下安装的路径,之后需要用 3.首先说Hbuil ...

  3. UITableView点击每个Cell,Cell的子内容的收放

    关于点击TableviewCell的子内容收放问题,拿到它的第一个思路就是, 方法一: 运用UITableview本身的代理来处理相应的展开收起: 1.代理:- (void)tableView:(UI ...

  4. JavaScript线程机制

    浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:JS引擎线程(用于处理JS).GUI渲染线程(用于页面渲染).浏览器事件触发线程(用于控制交互). 除此之外 ...

  5. Visual Studio 中 Build 和 Rebuild 的区别

    因为之前写的程序比较小,编译起来比较快,所以一直都没有太在意 Build 和 Rebuild 之间的区别,后来发现两个还是有很大不同. Build 只针对在上次编译之后更改过的文件进行编译,在项目比较 ...

  6. Java类加载基本过程

    基本过程:   根据类的全限定名称加载定义类的二进制字节流. 将字节流代表的静态存储结构转化为方法区的运行时数据结构 内存中生成一个代表这个类的java.lang.Class对象,作为方法去这个类的各 ...

  7. SQL优化 查询语句中,用 inner join 作为过滤条件和用where作为过滤条件的区别

    前段时间遇到一个存储过程,参数之一是一个字符串,在存储过程中,把字符串拆分成一个临时表之后存为一个key值的临时表,作为其中一个查询条件, 逻辑实现上有两种处理方式 insert into #t se ...

  8. chkconfig

    chkconfig的级别: 0:关机 1:单用户模式 2:无网络支持的多用户模式 3:有网络支持的多用户模式 4:保留,未使用 5:有网络支持有X-Windows(图形界面)支持的多用户模式 6:重新 ...

  9. WPF 自定义窗口

    在WPF中,经常需要对窗口进行设置,下面讲讲常用的几个设置. 1.无边框窗口 WindowStyle="None" 窗口样式无 AllowsTransparency="T ...

  10. 《Note --- Unreal 4 --- behavior tree》

    Web: https://docs.unrealengine.com/latest/INT/Engine/AI/BehaviorTrees/index.html Test project: D:\En ...