【BZOJ2002】 [Hnoi2010]Bounce 弹飞绵羊 分块/LCT
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
HINT
Source
强行用分块做,算是另一种分块的用法,分块真奇妙啊。
受到了来自abclzr的细心教导,首先思考最普通的模拟,发现可以O(n)路径压缩,O(1)的查询,但是需要修改就变成了O(n^2)的修改,于是考虑分块,记录一下每个点跳出该点所在的块的步数,也就是在每块内进行路径压缩,还有记录每个点跳出块后到达的点,同样可以块内路径压缩完成,这样就变成了O(sqrt(n))的修改和查询,但是预处理是O(n*sqrt(n))的,虽然可以过,但是LCT更快啦啦,我偏要写分块啦啦,读入优化背了一晚上WA的锅啦啦啦MD。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define N 200010
using namespace std;
int pos[N],st[N],nx[N],k[N];
int n,m,q,block;
inline int read ()
{
char c;
int ans=;
while ((c=getchar())=='\n' || c==' ' || c=='\r');
ans=c-'';
while (isdigit(c=getchar())) ans=ans*+c-'';
return ans;
}
int solve(int x)
{
int ans=;
while ()
{
ans+=st[x];
if (!nx[x]) return ans;
x=nx[x];
}
}
int main()
{
n=read();
block=(int)(sqrt(n));
for (int i=;i<=n;i++)
{
pos[i]=(i-)/block+;
k[i]=read();
}
for (int i=n;i>=;i--)
{
if (i+k[i]>n) st[i]=;
else if (pos[i]==pos[i+k[i]])
{
st[i]=st[i+k[i]]+;
nx[i]=nx[i+k[i]];
}
else
{
st[i]=;
nx[i]=i+k[i];
}
}
q=read();
for (int i=;i<=q;i++)
{
int x,y,z;
x=read();y=read();
y++;
if (x==) printf("%d\n",solve(y));
else
{
z=read();
k[y]=z;
for (int j=y;j>=(pos[y]-)*block+;j--)
{
if (j+k[j]>n) st[j]=,nx[j]=;
else if (pos[j]==pos[j+k[j]])
{
st[j]=st[j+k[j]]+;
nx[j]=nx[j+k[j]];
}
else
{
st[j]=;
nx[j]=j+k[j];
}
}
}
}
return ;
}
2016.3.24 学LCT,这果然是模板题。。。
#include <iostream>
#include <cstdio>
#define N 200020
using namespace std;
int n,m;
struct SplayNode
{
SplayNode *fa,*ch[];
int step;
bool chr() {return this==fa->ch[];}
bool check() {return this!=fa->ch[] && this !=fa->ch[];}
void updata() {step=ch[]->step+ch[]->step+;}
}*lct[N],*null;
inline int read() {int ans=; char c; while ((c=getchar())>'' || c<''); ans=c-''; while (isdigit(c=getchar())) ans=ans*+c-''; return ans;}
inline void MakeTree(SplayNode *x) {x->fa=x->ch[]=x->ch[]=null; x->step=;}
void init() {null=new SplayNode; null->fa=null->ch[]=null->ch[]=null; null->step=;}
inline void rotate(SplayNode *x)
{
SplayNode *r=x->fa;
int t=x->chr();
if (!r->check()) r->fa->ch[r->chr()]=x;
x->fa=r->fa;
r->ch[t]=x->ch[t^];
r->ch[t]->fa=r;
r->fa=x;
x->ch[t^]=r;
r->updata();
}
inline void splay(SplayNode *x)
{
for (;!x->check();rotate(x))
if (!x->fa->check())
if (x->chr()==x->fa->chr()) rotate(x->fa);
else rotate(x);
x->updata();
}
inline SplayNode *access(SplayNode *x)
{
SplayNode *y=null;
for (;x!=null;y=x,x=x->fa)
{
splay(x);
x->ch[]=y;
}
return y;
}
inline void link(SplayNode *x,SplayNode *y)
{
access(x); splay(x);
x->ch[]->fa=null; x->ch[]=null; x->fa=y; x->updata();
}
int main()
{
init();
n=read();
for (int i=;i<n;i++)
{
lct[i]=new SplayNode;
MakeTree(lct[i]);
}
for (int i=;i<n;i++)
{
int x;
x=read();
if (i+x<n) lct[i]->fa=lct[i+x];
}
m=read();
for (int i=;i<=m;i++)
{
int temp,x,y;
temp=read(); x=read();
if (temp==)
{
access(lct[x]);
splay(lct[x]);
printf("%d\n",lct[x]->step);
}
else
{
y=read();
if (x+y<n) link(lct[x],lct[x+y]);
else link(lct[x],null);
}
}
return ;
}
LCT
【BZOJ2002】 [Hnoi2010]Bounce 弹飞绵羊 分块/LCT的更多相关文章
- bzoj2002: [Hnoi2010]Bounce 弹飞绵羊 [分块][LCT]
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
- BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 【LCT】【分块】
BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始, ...
- [bzoj2002][Hnoi2010]Bounce弹飞绵羊——分块
Brief description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装 ...
- BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊(LCT)
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在 他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装 ...
- bzoj2002 [Hnoi2010]Bounce 弹飞绵羊——分块
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 第一次用分块,感觉超方便啊: 如果记录每个点的弹力系数,那么是O(1)修改O(n)查询 ...
- bzoj2002: [Hnoi2010]Bounce 弹飞绵羊 分块
这个题体现了分块不只是最大值最小值众数次数,而是一种清真的思想. 我们把整个序列分块,在每个块里处理每个位置跳出这个块的次数和跳出的位置,那么每次修改n0.5,每次查询也是,那么O(m* n0.5)的 ...
- bzoj2002 [Hnoi2010]Bounce 弹飞绵羊【LCT】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 第一道LCT,调了3天,发现是智障bug,我的青春... 主要参考了黄学长的代码,也没 ...
- 【bzoj2002】[Hnoi2010]Bounce 弹飞绵羊 分块
[bzoj2002][Hnoi2010]Bounce 弹飞绵羊 2014年7月30日8101 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀 ...
- [BZOJ2002][洛谷P3203][Hnoi2010]Bounce 弹飞绵羊(LCT维护链长)
luogu传送门 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 16082 Solved: ...
随机推荐
- 【转载】Python编写简易木马程序
转载来自: http://drops.wooyun.org/papers/4751?utm_source=tuicool 使用Python编写一个具有键盘记录.截屏以及通信功能的简易木马. 首先准备好 ...
- 【JAVA网络流之TCP与UDP 】
一.ServerSocket java.lang.Object |-java.net.ServerSocket 有子类SSLServerSocket. 此类实现服务器套接字.服务器套接字等待请求通过网 ...
- C++中的虚函数(表)实现机制以及用C语言对其进行的模拟实现
tfref 前言 C++对象的内存布局 只有数据成员的对象 没有虚函数的对象 拥有仅一个虚函数的对象 拥有多个虚函数的对象 单继承且本身不存在虚函数的继承类的内存布局 本身不存在虚函数(不严谨)但存在 ...
- php开启mysqli扩展之后如何连接数据库
Mysqli是php5之后才有的功能,没有开启扩展的朋友可以打开您的php.ini的配置文件;相对于mysql有很多新的特性和优势,需要了解的朋友可以参考下 Mysqli是php5之后才有的功能,没有 ...
- SQL常见错误及处理方法
1.情况:数据库引擎安装失败,报类似权限不足的错误 解决:可能由于计算机名和用户名相同导致,更改计算机名,卸载干净重装即可
- 修改Apache配置文件开启gzip压缩传输
转自:http://down.chinaz.com/server/201202/1645_1.htm 最近无事研究一些Web的优化,用工具page speed检测网站时发现还没有开启gzip压缩,于是 ...
- dojo.publish 和 dojo.subscribe
原文链接:http://www.cnblogs.com/didi/archive/2010/06/13/1757894.html //dojo.publish 和 dojo.subscribe :d ...
- 全面解析windows下Memcache技术应用
原文 http://www.cnblogs.com/liuqin520/p/4615644.html 一.Memcache介绍 Memcache 是 danga.com 的一个项目,最早是为 L ...
- 本人经过测试认为最简单最好的popupwindow样式
<shape xmlns:android="http://schemas.android.com/apk/res/android" > <!-- solid 设置 ...
- .net发邮件【转】
对于.NET而言,从2.0开始,发邮件已经是一件非常easy 的事了.下面我给出一个用C#群发邮件的实例,做了比较详细的注解,希望对有需要的朋友有所help. // 引入命名空间using Syste ...