BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊
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
1 2 1 1
3
1 1
2 1 1
1 1
Sample Output
3
HINT
Source
将跳转看成边的关系,易知这些转移边形成一棵树。如果以“弹出去”这个状态为根节点,从一个点出发的步数可以转换为深度,或者说是从根节点到这个点的距离。改变一个点的系数,可以视为改变一个点的父节点,但是其子树不会受到影响。显然是个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 弹飞绵羊的更多相关文章
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 分块
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...
- bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 動態樹
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 4055 Solved: 2172[Submi ...
- bzoj 2002 : [Hnoi2010]Bounce 弹飞绵羊 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 题面: 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2843 Solved: 1519[Submi ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 【分块】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 ...
- BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊:分块
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 题意: 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆 ...
- 【刷题】BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
- 洛谷 P3203 BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊
题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系 ...
随机推荐
- sed的应用
h3 { color: rgb(255, 255, 255); background-color: rgb(30,144,255); padding: 3px; margin: 10px 0px } ...
- [转]ThoughtWorks(中国)程序员读书雷达
http://agiledon.github.io/blog/2013/04/17/thoughtworks-developer-reading-radar/#rd?sukey=f64bfa68330 ...
- LintCode389.判断数独是否合法
LintCode简单题:判断数独是否合法 问题描述: 请判定一个数独是否有效. 该数独可能只填充了部分数字,其中缺少的数字用 . 表示. 注意事项: 一个合法的数独(仅部分填充)并不一定是可解的.我们 ...
- DLL组件注册器
在实际程序运行中,尤其是绿色软件,都需要对DLL进行注册才能够使用.下面就是笔者开发的一款简单的DLL注册器. http://pan.baidu.com/s/1mhbrN1e
- MS SQL巡检系列——检查重复索引
前言感想:一时兴起,突然想写一个关于MS SQL的巡检系列方面的文章,因为我觉得这方面的知识分享是有价值,也是非常有意义的.一方面,很多经验不足的人,对于巡检有点茫然,不知道要从哪些方面巡检,另外一方 ...
- JavaScript错误/异常处理
JavaScript Try...Catch 语句 介绍:JavaScript中的try...carch语句的作用和C#中的try...catch语句的作用一样, 都是捕获并处理异常. 语法: try ...
- 学习sql中的排列组合,在园子里搜着看于是。。。
学习sql中的排列组合,在园子里搜着看,看到篇文章,于是自己(新手)用了最最原始的sql去写出来: --需求----B, C, F, M and S住在一座房子的不同楼层.--B 不住顶层.C 不住底 ...
- ajax请求成功后打开新开窗口(window.open())被拦截的解决方法
问题:今天在做项目时需要在ajax请求成功后打开一个新的窗口,此时遇到浏览拦截了新窗口的问题,尝试在ajax 回调函数中模拟执行 click 或者 submit 等用户行为(trigger('clic ...
- Visual Studio Emulator for Android 初体验
Visual Studio Emulator for Android已经推出一段时间了,但一直没有用过.前两天下载安装用了下,整体感觉比谷歌自带的模拟器强多了.Visual Studio Emulat ...
- Web site collections
Integration 伯乐在线 极客头条 Hacker News Stack Overflow RFC Search Security Python Hacker - Freebuf PrimalS ...