[HNOI 2010]Bounce 弹飞绵羊
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
题解
首先,建立一个虚拟节点$n+1$,绵羊到达这个节点即被弹飞。
对于每个装置,
如果$i+K_i<=n$,则执行$Link(i,i+K_i)$,否则$Link(i,n+1)$。
对于修改操作,先执行$Cut(j,j+K_j)$(如果$j+K_j>n$则为$n+1$),再执行$Link(j,j+k)$(如果$j+k>n$则为$n+1$),
并把$K_j$赋为$k$。
对于询问操作,分别执行$MakeRoot(n+1)$,$MakeRoot(x)$,最终答案即为$size[x]-1$。
其中$size[i]$表示平衡树中节点$i$的子树的大小。
//It is made by Awson on 2017.12.24
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
using namespace std;
const int N = ; int n, m, k[N+], opt, a, b;
struct Link_Cut_Tree {
int ch[N+][], pre[N+], size[N+], isrt[N+], rev[N+];
Link_Cut_Tree () {
memset(isrt, , sizeof(isrt));
}
void pushup(int o) {
if (!o) return;
size[o] = size[ch[o][]]+size[ch[o][]]+;
}
void pushdown(int o) {
if (!o || !rev[o]) return;
int ls = ch[o][], rs = ch[o][];
swap(ch[ls][], ch[ls][]), swap(ch[rs][], ch[rs][]);
rev[ls] ^= , rev[rs] ^= , rev[o] = ;
}
void push(int o) {
if (!isrt[o]) push(pre[o]);
pushdown(o);
}
void rotate(int o, int kind) {
int p = pre[o];
ch[p][!kind] = ch[o][kind], pre[ch[o][kind]] = p;
if (isrt[p]) isrt[o] = , isrt[p] = ;
else ch[pre[p]][ch[pre[p]][] == p] = o;
pre[o] = pre[p];
ch[o][kind] = p, pre[p] = o;
pushup(ch[o][kind]), pushup(o);
}
void splay(int o) {
push(o);
while (!isrt[o]) {
if (isrt[pre[o]]) rotate(o, ch[pre[o]][] == o);
else {
int p = pre[o], kind = ch[pre[p]][] == p;
if (ch[p][kind] == o) rotate(o, !kind), rotate(o, kind);
else rotate(p, kind), rotate(o, kind);
}
}
}
void access(int o) {
int y = ;
while (o) {
splay(o); size[o] -= size[ch[o][]];
isrt[ch[o][]] = , isrt[ch[o][] = y] = ;
o = pre[y = o];
pushup(o);
}
}
void makeroot(int o) {
access(o), splay(o);
rev[o] ^= , swap(ch[o][], ch[o][]);
}
void link(int x, int y) {
makeroot(x); pre[x] = y;
}
void cut(int x, int y) {
makeroot(x), access(y), splay(y);
size[y] -= size[x];
ch[y][] = pre[x] = , isrt[x] = ;
}
int query(int x) {
makeroot(n+), makeroot(x);
return size[x]-;
}
}T; void work() {
scanf("%d", &n);
for (int i = ; i <= n; i++) T.size[i] = ;
for (int i = ; i <= n; i++) {
scanf("%d", &k[i]);
T.link(i, Min(k[i]+i, n+));
}
scanf("%d", &m);
while (m--) {
scanf("%d", &opt);
if (opt == ) {
scanf("%d", &a); a++;
printf("%d\n", T.query(a));
}else {
scanf("%d%d", &a, &b); a++;
T.cut(a, Min(k[a]+a, n+));
k[a] = b;
T.link(a, Min(k[a]+a, n+));
}
}
}
int main() {
work();
return ;
}
[HNOI 2010]Bounce 弹飞绵羊的更多相关文章
- 【BZOJ 2002】【Hnoi 2010】弹飞绵羊 分块||Link Cut Tree 两种方法
ShallWe,Yveh,hmy,DaD3zZ,四人吃冰糕从SLYZ超市出来后在马路上一字排开,,,吃完后发现冰糕棍上写着:“向狮子座表白:愿做你的小绵羊”,,, 好吧在这道题里我们要弹飞绵羊,有分块 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 9071 Solved: 4652[Submi ...
- 【bzoj2002】[Hnoi2010]Bounce 弹飞绵羊 link-cut-tree
2016-05-30 11:51:59 用一个next数组,记录点x的下一个点是哪个 查询时,moveroot(n+1),access(x),splay(x) ,输出size[ch[x][0]]即为答 ...
- 【bzoj2002】[Hnoi2010]Bounce 弹飞绵羊 分块
[bzoj2002][Hnoi2010]Bounce 弹飞绵羊 2014年7月30日8101 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀 ...
- 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 ...
- Bounce 弹飞绵羊
Bounce 弹飞绵羊 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 分块 将整个大区间分成若干块,每个点维护到下一个块需要跳的次 ...
- bzoj 2002 : [Hnoi2010]Bounce 弹飞绵羊 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 题面: 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: ...
随机推荐
- 【java并发系列】Fork/Join任务(转)
原文链接 当我们需要执行大量的小任务时,有经验的Java开发人员都会采用线程池来高效执行这些小任务.然而,有一种任务,例如,对超过1000万个元素的数组进行排序,这种任务本身可以并发执行,但如何拆解成 ...
- Beta冲刺链接总汇
Beta冲刺 咸鱼 Beta 冲刺day1 Beta 冲刺day2 Beta 冲刺day3 Beta 冲刺day4 Beta 冲刺day5 Beta 冲刺day6 Beta 冲刺day7 凡事预则立- ...
- TRY
- 实现mypwd
1 学习pwd命令 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 实现mypwd 4 测试mypwd 提交过程博客的链接 代码如图
- django BBS
https://github.com/triaquae/py_training/tree/master/OldboyBBS2 http://www.cnblogs.com/zhming26/p/592 ...
- STL常用整理
S T L Sting: << 判断拼音序 size length 字符串长度 str[n] 代表字符串中的一个字符 可用作左值 string::size_type 用于表示字符串长度计量 ...
- 构建微服务开发环境3————Java应用的优秀管理工具Maven的下载安装及配置
[内容指引] 下载安装包: MacOS下Maven的安装及配置: Windows下Maven的安装及配置. 一.下载安装包 进入Maven的官方下载地址:http://maven.apache.org ...
- 函数式编程之foldLeftViaFoldRight
问题来自 Scala 函数式编程 一书的习题, 让我很困扰, 感觉函数式编程有点神学的感觉.后面看懂之后, 又觉得函数式编程所提供的高阶抽象是多么的强大. 这个问题让我发呆了好久, 现在把自己形成的想 ...
- Python——cmd调用(os.system阻塞处理)
os.system(返回值为0,1,2) 0:成功 1:失败 2:错误 os.system默认阻塞当前程序执行,在cmd命令前加入start可不阻塞当前程序执行. 例如: import os os.s ...
- leetcode算法: Find Bottom Left Tree Value
leetcode算法: Find Bottom Left Tree ValueGiven a binary tree, find the leftmost value in the last row ...