2002. [HNOI2010]弹飞绵羊【LCT】
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
2
3
把每个点像弹到的点连边,显然可得出一棵树。
而x能弹几下显然就是x到树中在序列中最靠右的点的路径的size
可是如果维护森林的话,很难知道这个splay中最大的是哪一个
为了方便把弹飞的都连接到n+1点上,那么x弹的次数就是x到n+1的路径的size-1
查询和修改操作详见代码
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #define N (200000+100)
- using namespace std;
- int Father[N],Son[N][],Size[N],Rev[N];
- int n,m,a[N];
- int Get(int x) {return Son[Father[x]][]==x;}
- int Is_root(int x) {return Son[Father[x]][]!=x && Son[Father[x]][]!=x;}
- void Update(int x) {Size[x]=Size[Son[x][]]+Size[Son[x][]]+;}
- void Rotate(int x)
- {
- int wh=Get(x);
- int fa=Father[x],fafa=Father[fa];
- if (!Is_root(fa)) Son[fafa][Son[fafa][]==fa]=x;
- Father[fa]=x; Son[fa][wh]=Son[x][wh^];
- Father[x]=fafa; Son[x][wh^]=fa;
- if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
- Update(fa); Update(x);
- }
- void Pushdown(int x)
- {
- if (Rev[x] && x)
- {
- if (Son[x][]) Rev[Son[x][]]^=;
- if (Son[x][]) Rev[Son[x][]]^=;
- swap(Son[x][],Son[x][]);
- Rev[x]=;
- }
- }
- void Push(int x)
- {
- if (!Is_root(x)) Push(Father[x]);
- Pushdown(x);
- }
- void Splay(int x)
- {
- Push(x);
- for (int fa;!Is_root(x);Rotate(x))
- if (!Is_root(fa=Father[x]))
- Rotate(Get(fa)==Get(x)?fa:x);
- }
- void Access(int x) {for (int y=;x;y=x,x=Father[x]) Splay(x),Son[x][]=y,Update(x);}
- void Make_root(int x) {Access(x); Splay(x); Rev[x]^=;}
- int Find_root(int x) {Access(x); Splay(x); while (Son[x][]) x=Son[x][]; return x;}
- void Link(int x,int y) {Make_root(x); Father[x]=y;}
- void Cut(int x,int y) {Make_root(x); Access(y); Splay(y); Father[x]=Son[y][]=;}
- void Query(int x) {Make_root(n+); Access(x); Splay(x); printf("%d\n",Size[x]-);}
- void Change(int x,int y) {Cut(x,x+a[x]<=n?x+a[x]:n+); Link(x,x+y<=n?x+y:n+); a[x]=y;}
- int main()
- {
- int opt,x,y;
- scanf("%d",&n);
- for (int i=;i<=n;++i)
- {
- scanf("%d",&a[i]);
- if (i+a[i]<=n) Link(i,i+a[i]);
- else Link(i,n+);
- }
- scanf("%d",&m);
- for (int i=;i<=m;++i)
- {
- scanf("%d",&opt);
- if (opt==) scanf("%d",&x),Query(x+);
- if (opt==) scanf("%d%d",&x,&y),Change(x+,y);
- }
- }
2002. [HNOI2010]弹飞绵羊【LCT】的更多相关文章
- [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)
[BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree) 题面 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一 ...
- [Luogu P3203] [HNOI2010]弹飞绵羊 (LCT维护链的长度)
题面 传送门:洛谷 Solution 这题其实是有类似模型的. 我们先考虑不修改怎么写.考虑这样做:每个点向它跳到的点连一条边,最后肯定会连成一颗以n+1为根的树(我们拿n+1代表被弹出去了).题目所 ...
- 洛谷P3203 [HNOI2010] 弹飞绵羊 [LCT]
题目传送门 弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置, ...
- P3203 [HNOI2010]弹飞绵羊(LCT)
弹飞绵羊 题目传送门 解题思路 LCT. 将每个节点的权值设为\(1\),连接\(i\)和\(i+ki\),被弹飞就连上\(n\),维护权值和\(sum[]\).从\(j\)弹飞需要的次数就是\(sp ...
- BZOJ2002[Hnoi2010]弹飞绵羊——LCT
题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系 ...
- BZOJ.2002.Bounce 弹飞绵羊(LCT)
题目链接 从一个点只能往后跳,即后继状态只有一个,那么拿nxt[x]做fa[x]啊!这样就成了一棵树,从每个点开始的答案是它到所在树的根节点的距离. nxt[]的更改即动态修改树边,用LCT即可. 这 ...
- P3203 [HNOI2010]弹飞绵羊(LCT)
P3203 [HNOI2010]弹飞绵羊 LCT板子 用一个$p[i]$数组维护每个点指向的下个点. 每次修改时cut*1+link*1就解决了 被弹出界时新设一个点,权为0,作为终点表示出界点.其他 ...
- bzoj 2002 Bounce 弹飞绵羊
bzoj 2002 Bounce 弹飞绵羊 设一个虚拟节点表示被弹飞,则每个点的后继点是唯一确定的,每个点向它的后继点连边,就形成了一颗树. 询问就是问某个节点到虚拟节点的路径长度,修改就删除原来向后 ...
- [HNOI2010] 弹飞绵羊 (分块)
[HNOI2010] 弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上 ...
随机推荐
- vue+SSM验证码实现
源码:https://github.com/HannahLihui/StudentManager-SSM/tree/master/SSM-git/StudentManager-SSM-master 1 ...
- 南阳nyoj 56 阶乘因式分解(一)
阶乘因式分解(一) 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 给定两个数m,n,其中m是一个素数. 将n(0<=n<=10000)的阶乘分解质因数, ...
- mysql行转列,列转行
行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现.用传统的方法,比较好理解.层次清 ...
- Python标准模块--concurrent.futures 进程池线程池终极用法
concurrent.futures 这个模块是异步调用的机制concurrent.futures 提交任务都是用submitfor + submit 多个任务的提交shutdown 是等效于Pool ...
- 记录在window平台安装python的第三库(py,whl)
在下载python的第三库文件的时候,有些库文件有exe的发行版,但是有些第三库并没有找到针对于window的可执行文件安装包即exe文件,而只有源代码文件即py文件,和whl文件. 下面记录一下在w ...
- Ubuntu下编译opencv 和Ubuntu使用ffmpeg实现音频、视频的抽取
一.使用Ubuntu编译opencv (前提是Ubuntu内已经正确配置了opencv,个人采用opencv3.2) g++ 1.cpp -o 1 `pkg-config --cflags --lib ...
- Eclipse工程 导入 Android Studio
最近Eclipse好多项目转Android Studio 百度翻看好多文章 这篇不错 特纪录下 地址:http://www.cnblogs.com/bluestorm/p/3757402.html 一 ...
- OpenGL学习--07--模型加载(obj)
1.tutorial07.cpp // Include standard headers #include <stdio.h> #include <stdlib.h> #inc ...
- JavaScript写九九乘法表
<script language=javascript> for(i=1;i<=9;i++){ for(j=1;j<=9;j++){ document.write (i+&qu ...
- Pwn with File结构体(三)
前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 前面介绍了几种 File 结构体的攻击方式,其中包括修改 vtab ...