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
/*
求每棵子树的节点数。
这个题很巧妙的是建立了一个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)的更多相关文章

  1. 2002: [Hnoi2010]Bounce 弹飞绵羊 - BZOJ

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

  2. Bounce 弹飞绵羊 HYSBZ - 2002 分块

    //预处理出以这个点为起点并跳出这个块的次数和位置 //更新一个点的弹力系数可以只更新这个点以及这个块内之前的点 #include<stdio.h> #include<algorit ...

  3. bzoj 2002 Bounce 弹飞绵羊

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

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

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

  5. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 9071  Solved: 4652[Submi ...

  6. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 分块

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...

  7. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...

  8. bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 動態樹

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 4055  Solved: 2172[Submi ...

  9. bzoj 2002 : [Hnoi2010]Bounce 弹飞绵羊 (LCT)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 题面: 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: ...

  10. BZOJ 2002:Bounce 弹飞绵羊(分块)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 14944  Solved: 7598 [Su ...

随机推荐

  1. P2712 摄像头

    题目描述 食品店里有n个摄像头,这种摄像头很笨拙,只能拍摄到固定位置.现有一群胆大妄为的松鼠想要抢劫食品店,为了不让摄像头拍下他们犯罪的证据,他们抢劫前的第一件事就是砸毁这些摄像头. 为了便于砸毁摄像 ...

  2. IOS存储目录documents你在哪里啊

    iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么. documents,tmp,app,Library. (NSHomeDirectory ...

  3. Redis学习笔记(五)散列进阶

    HEXISTS key_name key(检查键key是否存在) HKEYS key_name(获得散列的所有键) HVALS key_name(获得散列的所有值) HINCRBY key_name ...

  4. 聊聊JavaScript和Scala的表达式 Expression

    我们先看下面这段简单的JavaScript代码. 我在第10行调用了函数f,其中传入的第二个和第三个参数都是一个逗号表达式. 函数f的实现,会检查这两个参数的类型,如果是函数,则执行函数调用,再打印其 ...

  5. Android(java)学习笔记168:Activity 4 种启动模式

    1. 任务栈(task stack): 任务栈 是用来记录用户操作的行为,维护一个用户体验. 一个应用程序一般都是由多个activity组成的. 任务栈(task stack)记录存放用户开启的act ...

  6. elasticsearch时间格式DateFormat的含义

    时间格式 枚举(或者英文)format pattern 含义 custom - 自定义属性 none - 不转化 basic_date yyyyMMdd 基本时间 basic_date_time   ...

  7. TensorFlow低阶API(四)—— 图和会话

    简介 TensorFlow使用数据流图将计算表示为独立的指令之间的依赖关系.这可生成低级别的编程模型,在该模型中,您首先定义数据流图,然后创建TensorFlow会话,以便在一组本地和远程设备上运行图 ...

  8. C# string补位

    参考:https://www.cnblogs.com/zhangqs008/archive/2012/02/01/2341078.html //1.1.左补位 "; , 'A'); //1. ...

  9. PowerShell(PHPStorm terminal with PowerShell)运行git log中文乱码

    解决方案: 1)以管理员身份运行PowerShell 2)新建一个针对PowerShell的Pofile文件 New-Item -Path $Profile -ItemType file -Force ...

  10. composer 设置代理

    在命令行终端中输入以下内容: export https_proxy='192.168.1.133:1080' export http_proxy='192.168.1.133:1080' 此前提是你已 ...