[HNOI2010]弹飞绵羊
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
先建树,如果i+k大于n,就和n+1,建边表示弹出,否则和i+k建边
建树用LCT的link操作
修改就cut操作删掉旧边,加上新边
查询时,把n+1变为树根,把x到n+1都变为实根
查询路径上节点数-1输出
splay维护size,因为总是只有一颗完整的树,所以不需要判断cut和link操作的可行性
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- int size[],ch[][],rev[],pre[],isrt[],n,m,k[];
- void pushup(int o)
- {
- if (!o) return;
- size[o]=size[ch[o][]]+size[ch[o][]]+;
- }
- void pushdown(int o)
- {
- if (!o) return;
- if (rev[o])
- {
- int ls=ch[o][],rs=ch[o][];
- rev[ls]^=;
- swap(ch[ls][],ch[ls][]);
- rev[rs]^=;
- swap(ch[rs][],ch[rs][]);
- rev[o]=;
- }
- }
- void push(int o)
- {
- if (isrt[o]==) push(pre[o]);
- pushdown(o);
- }
- void rotate(int o,bool kind)
- {
- int p=pre[o];
- ch[p][!kind]=ch[o][kind];pre[ch[o][kind]]=p;
- if (isrt[p]) isrt[p]=,isrt[o]=;
- else ch[pre[p]][ch[pre[p]][]==p]=o;
- pre[o]=pre[p];
- ch[o][kind]=p;pre[p]=o;
- pushup(p);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);
- isrt[ch[o][]]=;
- isrt[ch[o][]=y]=;
- pushup(o);
- y=o;o=pre[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);
- ch[y][]=;pre[x]=;
- isrt[x]=;
- pushup(y);
- }
- int main()
- {int i,c,x,y,st,ed;
- cin>>n;
- for (i=;i<=n+;i++)
- isrt[i]=,size[i]=;
- for (i=;i<=n;i++)
- {
- scanf("%d",&k[i]);
- if (i+k[i]>n) link(i,n+);
- else link(i,i+k[i]);
- }
- cin>>m;
- for (i=;i<=m;i++)
- {
- scanf("%d",&c);
- if (c==)
- {
- scanf("%d",&x);x++;
- makeroot(n+);
- access(x);
- splay(x);
- printf("%d\n",size[x]-);
- }
- else
- {
- scanf("%d%d",&x,&y);x++;
- if (k[x]+x>n) st=n+;
- else st=k[x]+x;
- if (y+x>n) ed=n+;
- else ed=y+x;
- k[x]=y;
- if (st!=ed)
- {
- cut(x,st);
- link(x,ed);
- }
- }
- }
- }
LCT
还有分块的做法
把n个点分成$sqrt n$块
预处理出f[i],s[i]
f[i]表示i会跳到下一块的地方
s[i]表示i跳到f[i]所需要的步数
查询时直接往后跳,最多跳$sqrt n$块
修改时只修改那一块$sqrt n$个元素
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- int n,k[],lim,s[],f[],m;
- int main()
- {int i,j,opt,x,now,cnt,y;
- cin>>n;
- for (i=;i<=n;i++)
- {
- scanf("%d",&k[i]);
- }
- lim=sqrt(n);
- for (i=;i<=n;i+=lim)
- {
- for (j=min(n,i+lim-);j>=i;j--)
- {
- if (k[j]+j>min(n,i+lim-)) s[j]=,f[j]=k[j]+j;
- else s[j]=s[j+k[j]]+,f[j]=f[k[j]+j];
- }
- }
- cin>>m;
- for (i=;i<=m;i++)
- {
- scanf("%d%d",&opt,&x);x++;
- if (opt==)
- {
- cnt=;
- while (x<=n)
- {
- cnt+=s[x];
- x=f[x];
- }
- printf("%d\n",cnt);
- }
- else
- {
- scanf("%d",&y);
- k[x]=y;
- if (x%lim==) now=x-lim+;
- else now=x-x%lim+;
- for (j=min(n,now+lim-);j>=now;j--)
- {
- if (k[j]+j>min(n,now+lim-)) s[j]=,f[j]=k[j]+j;
- else s[j]=s[j+k[j]]+,f[j]=f[k[j]+j];
- }
- }
- }
- }
分块
[HNOI2010]弹飞绵羊的更多相关文章
- P3203 [HNOI2010]弹飞绵羊(LCT)
P3203 [HNOI2010]弹飞绵羊 LCT板子 用一个$p[i]$数组维护每个点指向的下个点. 每次修改时cut*1+link*1就解决了 被弹出界时新设一个点,权为0,作为终点表示出界点.其他 ...
- [HNOI2010] 弹飞绵羊 (分块)
[HNOI2010] 弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上 ...
- 洛谷 P3203 [HNOI2010]弹飞绵羊 解题报告
P3203 [HNOI2010]弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一 ...
- [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)
[BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree) 题面 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一 ...
- 「洛谷P3202」[HNOI2010]弹飞绵羊 解题报告
P3203 [HNOI2010]弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一 ...
- [Luogu P3203] [HNOI2010]弹飞绵羊 (LCT维护链的长度)
题面 传送门:洛谷 Solution 这题其实是有类似模型的. 我们先考虑不修改怎么写.考虑这样做:每个点向它跳到的点连一条边,最后肯定会连成一颗以n+1为根的树(我们拿n+1代表被弹出去了).题目所 ...
- P3203 [HNOI2010]弹飞绵羊 —— 懒标记?分块?LCT?...FAQ orz
好久没写博客了哈,今天来水一篇._(:з」∠)_ 题目 :弹飞绵羊(一道省选题) 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏 ...
- P3203 [HNOI2010]弹飞绵羊 —— 懒标记?分块?
好久没写博客了哈,今天来水一篇._(:з」∠)_ 题目 :弹飞绵羊(一道省选题) 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏 ...
- 洛谷P3203 [HNOI2010] 弹飞绵羊 [LCT]
题目传送门 弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置, ...
- P3203 [HNOI2010]弹飞绵羊(LCT)
弹飞绵羊 题目传送门 解题思路 LCT. 将每个节点的权值设为\(1\),连接\(i\)和\(i+ki\),被弹飞就连上\(n\),维护权值和\(sum[]\).从\(j\)弹飞需要的次数就是\(sp ...
随机推荐
- 网络1711c语言第0次作业总结
作业地址:https://edu.cnblogs.com/campus/jmu/JMUC--NE17111712/homework/861 总结 1.评分标准 以下要求中除了未交和抄袭0分,其他项最多 ...
- react基础篇入门组件
讲述一下React: 1.声明式设计-React采用声明范式,可以轻松描述应用 2.高效-React通过DOM模型,最大限度的减少dom的交互 3.灵活-React可以与已知的库或框架很好的配合 4. ...
- python之路--day6--字符编码
一.知识储备 cpu--控制和运算 内存--暂时存储cpu需要的数据 硬盘--永久保存数据2.文本编辑器的原理存储原理 1,启动文本编辑器 2,在编辑器上输入内容---此时输入内容还在内存上 3,保存 ...
- php函数var_dump() 、print_r()、echo()
var_dump() 能打印出类型 print_r() 只能打出值 echo() 是正常输出... 需要精确调试的时候用 var_dump(); 一般查看的时候用 print_r() 另外 , ech ...
- MSIL实用指南-一维数组的操作
本篇讲解怎么生成和操作一维数组.各种数组类型创建的步骤是一样的,但是加载和保存步骤有所不同. 一.创建数组所有类型的一维数组创建都是一样的,分三步.1.加载数组长度2.生成指令 Newarr < ...
- Linux的打印rpm包的详细信息的shell脚本
#!/bin/bash # list a content summary of a number of RPM packages # USAGE: showrpm rpmfile1 rpmfile2 ...
- margin-top塌陷
margin-top 塌陷 在两个不浮动的盒子嵌套时候,内部的盒子设置的margin-top会加到外边的盒子上,导致内部的盒子margin-top设置失败,解决方法如下: 1.外部盒子设置一个边框: ...
- mysql中的视图、事务和索引
视图: 对于一个sql查询,如果发生了修改,就需要修改sql语句. 我们可以通过定义视图来解决问题.改变需求之后就改变视图. 视图是对查询的封装 定义视图: create view 视图名称 as s ...
- python/匿名函数和内置函数
1 匿名函数 匿名函数是lambda定义的没有名字的具有一些小功能的函数 具体形式是 lambda 参数列表:返回值表达式 lambda x: X**2 # 求平方操作 lambda x: x> ...
- 道可道,非常道——详解promise
promise 出来已久,以前一直使用,没有仔细剖析原理,最近在复习es6的知识,写一下自己对于promise的理解. promise是es6的一种异步编程解决方案,避免频繁的回调函数,增强代码的可阅 ...