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. AJPFX关于表结构的相关语句

    //表结构的相关语句==================================== 建表语句: create table 表名(                                ...

  2. 关于对象.style currentstyle 的区别

    对象.style的方式只能获取行内写法的样式,但是外部引入的或者写在head里面的就无法获取,只能用currentstyle.

  3. Qt窗口-仅显示关闭按钮

    环境: Qt5.3.1, mac os x 10.10.1 setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowH ...

  4. JS:输出9*9乘法表

    <html> <head> <title>9*9 multiplication table</title> </head> <body ...

  5. Linux下scp报Permission denied错误的解决方法

    sudo vim /etc/ssh/sshd_config 把PermitRootLogin no改成PermitRootLogin yes如果原来没有这行或被注释掉,就直接加上PermitRootL ...

  6. IDEA无法编译源码,IDEA查看源码出现/* compiled code */

    打开Settings -> Plugins    搜索dec,选中,确定,重启,解决

  7. install mysql at linux

    cd /usr/local wget http://repo.mysql.com//mysql57-community-release-el7-7.noarch.rpm rpm -ivh mysql5 ...

  8. cc.Component

    组件入口函数1: onLoad: 组件加载的时候调用, 保证了你可以获取到场景中的其他节点,以及节点关联的资源数据;2: start: 也就是第一次执行 update 之前触发;3: update(d ...

  9. MySQL字符集设定与查询

    一.字符集设定 MySQL数据库允许对服务器.数据库.数据表.数据列级别的字符集作出互不影响的设定. 1.对服务器字符集设定是通过配置文件中选项character-set-server 设置,如 ch ...

  10. 爬虫app信息抓取之apk反编译抓取

    之前也抓过一些app,数据都比较好取,也没有研究的太深,毕竟还有android 模拟器+ appium 的方法.直到遇见了一款app ,具体名字就不说了,它安装在模拟器上竟然打不开 !!第一次遇见上网 ...