BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 【LCT】【分块】
BZOJ2002 Hnoi2010 Bounce 弹飞绵羊
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
分块做法和LCT做法都有
先讲讲LCT,就是一个板子,把当前点和可以连到的点连边,然后修改弹力值就是把边断开然后重新连一条边,维护的答案是一条链的长度,在这里可以直接用LCT的性质直接维护siz
#include<bits/stdc++.h>
using namespace std;
#define N 200010
#define INF 1e9
inline int read(){
int res=0,w=1;char c=getchar();
while(!isdigit(c)&&c!='-')c=getchar();
if(c=='-')w=-1,c=getchar();
while(isdigit(c))res=(res<<1)+(res<<3)+c-'0',c=getchar();
return res;
}
struct Link_Cut_Tree{
int fa[N],son[N][2],siz[N];bool rev[N];
Link_Cut_Tree(){memset(rev,0,sizeof(rev));}
bool isroot(int t){return son[fa[t]][0]!=t&&son[fa[t]][1]!=t;}
bool Son(int t){return son[fa[t]][1]==t;}
void pushup(int t){siz[t]=siz[son[t][0]]+siz[son[t][1]]+1;}
void pushdown(int t){
if(!isroot(t))pushdown(fa[t]);
if(rev[t]){
rev[t]^=1;
rev[son[t][0]]^=1;
rev[son[t][1]]^=1;
swap(son[t][0],son[t][1]);
}
}
void rotate(int t){
int f=fa[t],g=fa[f];
bool a=Son(t),b=a^1;
if(!isroot(f))son[g][Son(f)]=t;fa[t]=g;
son[f][a]=son[t][b];fa[son[t][b]]=f;
son[t][b]=f;fa[f]=t;
pushup(f);pushup(t);
}
void splay(int t){
pushdown(t);
while(!isroot(t)){
int f=fa[t];
if(!isroot(f)){
if(Son(t)^Son(f))rotate(t);
else rotate(f);
}
rotate(t);
}
}
void access(int t){
int tmp=0;
while(t){
splay(t);
son[t][1]=tmp;
if(tmp)fa[tmp]=t;pushup(t);
tmp=t;t=fa[t];
}
}
void putroot(int t){
access(t);
splay(t);
rev[t]^=1;
}
void link(int x,int y){putroot(x);fa[x]=y;}
void cut(int x,int y){
putroot(x);
access(y);
splay(y);
son[y][0]=fa[x]=0;
pushup(y);
}
int query(int x,int y){
putroot(y);
access(x);
splay(x);
return siz[x]-1;
}
}lct;
int n,m,a[N];
int main(){
n=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++)
lct.link(i,(i+a[i]>n)?n+1:i+a[i]);
m=read();
for(int i=1;i<=m;i++){
int op,x,y;
scanf("%d",&op);
if(op==1){
scanf("%d",&x);x++;
printf("%d\n",lct.query(x,n+1));
}else{
scanf("%d%d",&x,&y);x++;
lct.cut(x,(x+a[x]>n)?n+1:x+a[x]);
a[x]=y;
lct.link(x,(x+a[x]>n)?n+1:x+a[x]);
}
}
return 0;
}
然后讲讲分块,每次暴力跳,维护一下每个点跳出当前块的操作次数,暴力修改暴力查询就好了
#include<bits/stdc++.h>
using namespace std;
#define INF 0x7fffffff
#define LL long long
#define N 1000010
const int siz=1000;
struct Temp{int to,tmp,bel;}a[N];
int n,m,pre[N];
int read(){
int ans=0,w=1;char c=getchar();
while(!isdigit(c)&&c!='-')c=getchar();
if(c=='-')c=getchar(),w=-1;
while(isdigit(c))ans=ans*10+c-'0',c=getchar();
return ans*w;
}
void modify(int x){
if(a[x+pre[x]].bel!=a[x].bel){
a[x].to=x+pre[x];
a[x].tmp=1;
}else{
a[x].to=a[x+pre[x]].to;
a[x].tmp=a[x+pre[x]].tmp+1;
}
return;
}
void build(){
for(int i=1;i<=n;i++)a[i].bel=(i-1)/siz+1;
for(int i=n;i>=1;i--)
if(i+pre[i]>n)a[i].tmp=1,a[i].to=0;
else modify(i);
}
int query(int x){
int ans=0;
while(x){
ans+=a[x].tmp;
x=a[x].to;
}
return ans;
}
int main(){
n=read();
for(int i=1;i<=n;i++)pre[i]=read();
build();
m=read();
for(int i=1;i<=m;i++){
int op=read(),x;
if(op==1){
x=read()+1;
printf("%d\n",query(x));
}else{
x=read()+1,pre[x]=read();
int fro=(a[x].bel-1)*siz+1;
for(int i=x;i>=fro;i--)modify(i);
}
}
return 0;
}
BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 【LCT】【分块】的更多相关文章
- [BZOJ2002] [Hnoi2010] Bounce 弹飞绵羊 (LCT)
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
- bzoj2002 [Hnoi2010]Bounce 弹飞绵羊【分块】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 这一题除了LCT解法,还有一种更巧妙,代码量更少的解法,就是分块.先想,如果仅仅记录每 ...
- [BZOJ2002][Hnoi2010]Bounce弹飞绵羊 LCT
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 建图,每次往后面跳就往目标位置连边,将跳出界的点设为同一个点.对于修改操作发现可以用 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 【分块】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 ...
- 2002: [Hnoi2010]Bounce 弹飞绵羊(分块)
2002: [Hnoi2010]Bounce 弹飞绵羊 时间限制: 10 Sec 内存限制: 259 MB 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...
- [bzoj2002][Hnoi2010]Bounce弹飞绵羊_LCT
Bounce弹飞绵羊 bzoj-2002 Hnoi-2010 题目大意:n个格子,每一个格子有一个弹簧,第i个格子会将经过的绵羊往后弹k[i]个,达到i+k[i].如果i+k[i]不存在,就表示这只绵 ...
- bzoj2002: [Hnoi2010]Bounce 弹飞绵羊 [分块][LCT]
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
- [bzoj2002][Hnoi2010]Bounce弹飞绵羊——分块
Brief description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装 ...
随机推荐
- 做文件上传下载时报这个错com.alibaba.fastjson.JSONException: illegal identifier : \
::-exec-] DEBUG c.i.e.m.I.insertDataEmebeding - <== Updates: ::-exec-] ERROR c.i.e.c.CaseArchiveC ...
- 将springboot项目发布到独立的tomcat中运行
在开发阶段我们推荐使用内嵌的tomcat进行开发,因为这样会方便很多,但是到生成环境,我希望在独立的tomcat容器中运行,因为我们需要对tomcat做额外的优化,这时我们需要将工程打包成war包发进 ...
- JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果
Ace模板地址:http://code.google.com/p/ace-engine/wiki/AceTemplate(有时会打不开) Ace英文官网:http://wrapbootstrap.co ...
- [java]Stream API——map和flatMap的区别
map方法 map的含义为映射.是指对于Stream中包含的每一个元素使用给定的转换函数进行转换. map传入的Lambda表达式必须是Function实例,参数可以为任意类型,而其返回值也是任性类型 ...
- 1-23-shell脚本之-if流程控制语句和for循环语句的使用
大纲: 1.逻辑判断 2.if流程控制语句 3.for循环控制语句 ---------------------------------------------- 在开始之前,先了解一下逻辑判断符号 ...
- 原生javascript-日历插件编写
在线实例:http://lgy.1zwq.com/calendar/ 按照我们常用的日历格式,是7*6的格子,所以生成格子的总数就确定为42 例子:(如:2013年8月,这个时间为例子) /*---- ...
- wii 入门之路--fatt
wii 入门之路--fatt system menu:系统界面,开机进入后,显示很多应用,4.1用IOS60. Channel:理解为界面中的软件应用和游戏. IOS:IOS(Input Output ...
- sql中exists,Intersect ,union 与union All的用法
熟练使用SQL Server中的各种用法会给查询带来很多方便.今天就介绍一下EXCEPT和INTERSECT.注意此语法仅在SQL Server 2005及以上版本支持. EXCEPT是指在第一个集合 ...
- yii2 联系我们发送邮件报错
为什么会报错,因为国内的邮件服务商要求发送邮件的人和设置的smtp服务器账号要相同,因为联系我们的是用户,也就是发件人是用户,而不是我们配置的邮箱,所有出错. 这里我用了个取巧的办法,发件人改为自己, ...
- trigger 触发器(mysql)
/* 触发器 tigger 引出触发器: 在进行数据库应用软件的开发的时候,我们有时候会碰到表中的某些数据改变,同事希望引起其他相关数据改变的需求,这时候就需要使用触发器. 运用触发器可以简化程序,增 ...