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

把每个点像弹到的点连边,显然可得出一棵树。
而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】的更多相关文章

  1. [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)

    [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree) 题面 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一 ...

  2. [Luogu P3203] [HNOI2010]弹飞绵羊 (LCT维护链的长度)

    题面 传送门:洛谷 Solution 这题其实是有类似模型的. 我们先考虑不修改怎么写.考虑这样做:每个点向它跳到的点连一条边,最后肯定会连成一颗以n+1为根的树(我们拿n+1代表被弹出去了).题目所 ...

  3. 洛谷P3203 [HNOI2010] 弹飞绵羊 [LCT]

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

  4. P3203 [HNOI2010]弹飞绵羊(LCT)

    弹飞绵羊 题目传送门 解题思路 LCT. 将每个节点的权值设为\(1\),连接\(i\)和\(i+ki\),被弹飞就连上\(n\),维护权值和\(sum[]\).从\(j\)弹飞需要的次数就是\(sp ...

  5. BZOJ2002[Hnoi2010]弹飞绵羊——LCT

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

  6. BZOJ.2002.Bounce 弹飞绵羊(LCT)

    题目链接 从一个点只能往后跳,即后继状态只有一个,那么拿nxt[x]做fa[x]啊!这样就成了一棵树,从每个点开始的答案是它到所在树的根节点的距离. nxt[]的更改即动态修改树边,用LCT即可. 这 ...

  7. P3203 [HNOI2010]弹飞绵羊(LCT)

    P3203 [HNOI2010]弹飞绵羊 LCT板子 用一个$p[i]$数组维护每个点指向的下个点. 每次修改时cut*1+link*1就解决了 被弹出界时新设一个点,权为0,作为终点表示出界点.其他 ...

  8. bzoj 2002 Bounce 弹飞绵羊

    bzoj 2002 Bounce 弹飞绵羊 设一个虚拟节点表示被弹飞,则每个点的后继点是唯一确定的,每个点向它的后继点连边,就形成了一颗树. 询问就是问某个节点到虚拟节点的路径长度,修改就删除原来向后 ...

  9. [HNOI2010] 弹飞绵羊 (分块)

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

随机推荐

  1. 转载:@Html.ValidationSummary(true)

    ASP.NET MVC3 Model验证总结 @Html.ValidationSummary(true)   http://www.wyjexplorer.cn/Post/2012/8/3/model ...

  2. 基于JSP的RSS阅读器的设计与实现

    阅读器访问地址:http://easyrss.tk/,欢迎体验! 阅读导览 一.    概述  二.    设计的基本概念和原理 三.    设计方案 四.    主要源代码 五.    阅读器使用说 ...

  3. php判断是否isPhone、is_weixin

    protected function isPhone(){ $agent = strtolower($_SERVER['HTTP_USER_AGENT']); //pc请求头信息数组 $pc_arr= ...

  4. java网络编程(UDP详解)

    UDP详解 一,TCP/IP协议栈中,TCP协议和UDP协议的联系和区别? 联系: TCP和UDP是TCP/IP协议栈中传输层的两个协议,它们使用网络层功能把数据包发送到目的地,从而为应用层提供网络服 ...

  5. 在arcgis使用python脚本进行字段计算时对中文的处理方案

    一.引言 在arcgis打开一个图层的属性表,可以对属性表的某个字段进行计算,但是在平常一般都是使用arcgis提供的字段计算器的界面进行傻瓜式的简答的赋值操作,并没有使用到脚本对字段值进行逻辑的操作 ...

  6. Elixir木蚂蚁支付服务器验签名方法

    官方范例为java public boolean verify(String sign , String appKey , String orderId) throws UnsupportedEnco ...

  7. redis中文

    Redis 是完全开源免费的,遵守BSD协议,先进的key - value持久化产品.它通常被称为数据结构服务器,因为值(value)可以是         字符串(String),         ...

  8. 带你从零学ReactNative开发跨平台App开发(四)

    ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...

  9. Debian出现in the drive ‘/media/cdrom/’ and press enter解决办法

    没有光盘源解决打开/etc/apt/sources.list文件,注释掉cdrom那一行,然后再执行apt-get update更新下deb仓库这样以后再使用apt-get安装时就不会再搜寻cdrom ...

  10. web assembly是什么,能干什么

    web assembly混合javascript和另外底层语言编译的模块,共同运行.将js的高级,易用及c/c++的高效底层优势结合起来. 最可能的用处是提供一种可行的方法将原来的c/c++应用por ...