弹飞绵羊(bzoj 2002)
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节点,但是不太清楚这个n+1节点在程序中起了什么作用。。。
*/
#include<iostream>
#include<cstdio>
#define N 200010
using namespace std;
int n,m;
int next[N],c[N][],fa[N],size[N],st[N];
bool rev[N];
bool isroot(int k){
return c[fa[k]][]!=k&&c[fa[k]][]!=k;
}
void pushup(int x){
size[x]=size[c[x][]]+size[c[x][]]+;
}
void pushdown(int k){
int l=c[k][],r=c[k][];
if(rev[k]){
rev[k]^=;rev[l]^=;rev[r]^=;
swap(c[k][],c[k][]);
}
}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
if(c[y][]==x)l=;else l=;r=l^;
if(!isroot(y)){
if(c[z][]==y)c[z][]=x;else c[z][]=x;
}
fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
pushup(y);pushup(x);
}
void splay(int x){
int top=;st[++top]=x;
for(int i=x;!isroot(i);i=fa[i])
st[++top]=fa[i];
for(int i=top;i;i--)pushdown(st[i]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if(c[y][]==x^c[z][]==y)rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x){
int t=;
while(x){
splay(x);
c[x][]=t;
t=x;x=fa[x];}
}
void rever(int x){
access(x);splay(x);rev[x]^=;
}
void link(int x,int y){
rever(x);fa[x]=y;splay(x);
}
void cut(int x,int y){
rever(x);access(y);splay(y);c[y][]=fa[x]=;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
int x;scanf("%d",&x);
fa[i]=x+i;size[i]=;
if(fa[i]>n+)fa[i]=n+;
next[i]=fa[i];
}
size[n+]=;
scanf("%d",&m);
for(int i=;i<=m;i++){
int f;scanf("%d",&f);
if(f==){
rever(n+);
int x;scanf("%d",&x);x++;
access(x);splay(x);printf("%d\n",size[c[x][]]);
}
else {
int x,y;scanf("%d%d",&x,&y);x++;
int t=min(n+,x+y);
cut(x,next[x]);link(x,t);next[x]=t;
}
}
return ;
}
/*
如果没有修改操作,可能会想预处理出在每个点被弹飞的步数,这样的查询是O(1)的,但由于有修改操作,
使每次操作的复杂度可能变成O(n),所以可以考虑一种折中的方法,分块!
对于每一块,处理出每个点跳出这个块的步数以及会落在哪一个点上,这样使查询和修改都变成了O(√n)。
*/
#include<cstdio>
#include<iostream>
#include<cmath>
#define N 200010
using namespace std;
int k[N],bl[N],stp[N],next[N],n,m,len;
void init(int x){
for(int i=(x-)*len+;i<=min(x*len,n);i++){
int tot=,pos=i;
while(pos<=n&&bl[pos]==x){
tot++;
pos+=k[pos];
}
stp[i]=tot;next[i]=pos;
}
}
int query(int x){
int ans=;
for(int i=x;i<=n;i=next[i])
ans+=stp[i];
return ans;
}
void modify(int x,int y){
k[x]=y;
for(int i=x;i>=(bl[x]-)*len+;i--){
if(i+k[i]>bl[x]*len) stp[i]=,next[i]=i+k[i];
else stp[i]=stp[i+k[i]]+,next[i]=next[i+k[i]];
}
}
int main(){
scanf("%d",&n);len=sqrt(n);
for(int i=;i<=n;i++){
scanf("%d",&k[i]);
bl[i]=(i-)/len+;
}
for(int i=;i<=bl[n];i++)
init(i);
scanf("%d",&m);
for(int i=;i<=m;i++){
int opt,x,y;scanf("%d%d",&opt,&x);x++;
if(opt==) printf("%d\n",query(x));
else scanf("%d",&y),modify(x,y);
}
return ;
}
弹飞绵羊(bzoj 2002)的更多相关文章
- 2002: [Hnoi2010]Bounce 弹飞绵羊 - BZOJ
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
- Bounce 弹飞绵羊 HYSBZ - 2002 分块
//预处理出以这个点为起点并跳出这个块的次数和位置 //更新一个点的弹力系数可以只更新这个点以及这个块内之前的点 #include<stdio.h> #include<algorit ...
- bzoj 2002 Bounce 弹飞绵羊
bzoj 2002 Bounce 弹飞绵羊 设一个虚拟节点表示被弹飞,则每个点的后继点是唯一确定的,每个点向它的后继点连边,就形成了一颗树. 询问就是问某个节点到虚拟节点的路径长度,修改就删除原来向后 ...
- [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)
[BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree) 题面 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 9071 Solved: 4652[Submi ...
- 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:Bounce 弹飞绵羊(分块)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 14944 Solved: 7598 [Su ...
随机推荐
- .net 音频转换 .amr 转 .mp3 (ffmpeg转换法)
最近看来是跟声音干上了啊! 音频转换的第二种方法,这种方法相对第一种来说,要简单的多! 首先,你得下载个“ffmpeg.exe” 插件,然后把它放到你的项目中,如下图: 程序中会调用该文件,以助于转换 ...
- 关于发布WP 8.1应用信息不匹配问题的解决办法
错误提示: 与此更新关联的程序包标识符与已上传程序包中的标识符不匹配: The package identity associated with this update doesn't match ...
- Elasticsearch (1) - 索引库 文档 分词
创建索引库 ES的索引库是一个逻辑概念,它包括了分词列表及文档列表,同一个索引库中存储了相同类型的文档.它就相当于MySQL中的表,或相当于Mongodb中的集合. 关于索引这个语: 索引(名词):E ...
- el-select,选择一行,取值行的对象.
<el-select v-model="set_invoice_form.InvoiceType" placeholder="请选择" :disabl ...
- java.lang.NoSuchMethodError: org.hibernate.cfg.Environment.verifyProperties
我在使用jpa2+spring4+hibernate4 的时候,报错java.lang.NoSuchMethodError: org.hibernate.cfg.Environment.verifyP ...
- 初识Vivado
Vivado 设计套件包括高度集成的设计环境和新一代从系统到 IC 级的工具,这些均建立在共享的可扩展数据模型和通用调试环境基础上.这也是一个基于 AMBA AXI4 互联规范.IP-XACT IP ...
- UVALive 2238 Fixed Partition Memory Management 固定分区内存管理(KM算法,变形)
题意:目前有一部分可用内存,分为m个大小固定的区域.现有n个程序要执行,每个程序在不同大小的内存中运行所需的时间不同,要使运行完所有程序所耗时最少,问每个程序在哪块区域中从什么时间运行到什么时间,以及 ...
- RPC(Remote Procedure Call Protocol)远程过程调用协议
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.RPC协议假定某些传输协议的存在 ...
- 职业生涯手记——记人生中第一次经历的产品上线——内测篇Day11
2017/08/21 产品内测期Day11 说出来可能你不信,原定于9月15号结束的内测活动,今天居然被甲方投诉导致强制停止,原因是这个内测活动没有经过批准,并且有用户打了甲方所在公司的客服部门,增加 ...
- 深入理解typeof操作符
typeof可以检测数据的类型 typeof返回结果的其实是字符串:可以通过以下测试出来 console.log( typeof(typeof(a))); // string typeof返回的数据类 ...