【BZOJ】2002: [Hnoi2010]Bounce 弹飞绵羊(lct)
http://www.lydsy.com/JudgeOnline/problem.php?id=2002
(BZOJ挂了,还没在BZOJ测,先是在wikioi测过了,,)
囧。在军训时立志要学lct!!!这是一道lct的裸题,只有access操作(10行都没有啊亲。。。缩行大法的话,我就不说了。。)(link操作相当于水过),其实lct很简单。。想想都有点小激动。。。。。。
lct用splay维护的话,一下就写好了。。但是我在写lct的时候,发现了一些我原来splay的老问题,我原来也知道了的,就是将null的ch给赋值了,因为在rot操作里没有特判,所以导致了null的孩子被赋值了,导致我的lct调试了2天T_T
这不科学啊!!(但是想想了还好了,,因为lct在splay的过程中,是有父亲而父亲不一定有这个孩子的,因为lct维护的是森林。。所以在splay里要加特判,即父亲是否有这个孩子
还有个地方卡了我的调试,就是access操作,本来我是没有加ch[1]->f=null的,之前调试的时候以为是这里出问题,但是证明我很蠢。。。。这里一定不能这样搞啊!因为这样就将孩子和父亲断了联系。。。囧。
本题有个特性,即已经有序了的,我们可以从后往前看这个数组,想象成森林,某根的孩子就是在原数组的左边(深度比他深,即越后的元素深度越浅,因为lct在找preferred path的时候splay是按深度构图的,那么孩子就是在父亲的左边,而羊是从左往右走的,所以在更新的时候,不能断了左边的联系T_T,就是我之前的那个错误。。。。将孩子的父亲断了。。T_T。)
link-cut tree具体看论文吧,很容易看懂的,真心话。就是用一颗splay维护某个点的路径,即access操作,我相信多做题就行了的
。。找到错误真开心~调试出来了真开心~
有时间在学习完整套lct然后写篇专题。。囧。。最近看的数学真心感觉有点难啊,数论怎么那么hentai啊?公式推来推去就是为了将O(n)变成O(1)么。这东西能在考场上想到吗囧。好吧,我是蒟蒻所以想不到。
#include <cstdio>
#define read(x) x=getint() using namespace std;
inline int getint() { char c; int ret=0; for(c=getchar(); c<'0' || c>'9'; c=getchar()); for(; c>='0' && c<='9'; c=getchar()) ret=ret*10+c-'0'; return ret; } const int N=200005;
struct node* null;
struct node {
node *f, *ch[2];
int s;
void pushup() { s=1+ch[0]->s+ch[1]->s; }
bool d() { return f->ch[1]==this; }
void setc(node* c, bool d) { ch[d]=c; c->f=this; }
bool check() { return f==null || (f->ch[0]!=this && f->ch[1]!=this); } //check操作是lct特地的,因为为了省空间,我们不开n颗splay,只用节点关联就行了,这样就无法避免父亲没有这个孩子的情况。所以还要特判
}*nd[N]; void rot(node* r) {
node* f=r->f; bool d=r->d();
if(f->check()) r->f=f->f;
else f->f->setc(r, f->d()); //这里一定要这样写,不然会让null的孩子改变,这样在splay的循环就会死循环T_T
f->setc(r->ch[!d], d);
r->setc(f, !d);
f->pushup();
} inline void splay(node* r) {
while(!r->check())
if(r->f->check()) rot(r);
else r->d()==r->f->d()?(rot(r->f), rot(r)):(rot(r), rot(r));
r->pushup();
} inline void access(node* f) {
for(node* c=null; f!=null; f=f->f) {
splay(f);
f->setc(c, 1);
f->pushup();
c=f;
}
} inline void link(node* c, node* f) {
access(c); splay(c);
c->ch[0]->f=null; c->ch[0]=null; c->f=f; c->pushup();
} inline void init() {
null=new node; null->s=0; null->f=null->ch[0]=null->ch[1]=null;
} int main() {
init();
int n, t; read(n);
for(int i=0; i<n; ++i) { nd[i]=new node; nd[i]->s=1; nd[i]->ch[0]=nd[i]->ch[1]=nd[i]->f=null; }
for(int i=0; i<n; ++i) {
read(t);
if(i+t<n) nd[i]->f=nd[i+t];
}
int m, a, b, c; read(m);
for(int i=0; i<m; ++i) {
read(a); read(b);
if(a==1) {
access(nd[b]);
splay(nd[b]);
printf("%d\n", nd[b]->s);
}
else {
read(c);
if(b+c<n) link(nd[b], nd[b+c]);
else link(nd[b], null);
}
}
return 0;
}
参考论文:杨哲《QTREE解法的一些研究》
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
【BZOJ】2002: [Hnoi2010]Bounce 弹飞绵羊(lct)的更多相关文章
- 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 弹飞绵羊 lct 动态树 splay
http://www.lydsy.com/JudgeOnline/problem.php?id=2002 http://blog.csdn.net/frods/article/details/5224 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (LCT维护深度)
要维护深度,就维护一下size就行了.access一下x,那么从根->x这一条链就独立成为一棵splay,那么splay的size节点数就是x的深度. 删边的时候直接access一下,splay ...
- bzoj 2002 : [Hnoi2010]Bounce 弹飞绵羊 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 题面: 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2843 Solved: 1519[Submi ...
- 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 弹飞绵羊 動態樹
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 4055 Solved: 2172[Submi ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 【分块】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 ...
- 【刷题】BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
随机推荐
- lucas定理,组合数学问题
对于C(n, m) mod p.这里的n,m,p(p为素数)都很大的情况.就不能再用C(n, m) = C(n - 1,m) + C(n - 1, m - 1)的公式递推了. 这里用到Lusac定理 ...
- 响应式Web设计(Responsive Web design)
中文名 响应式Web设计 提出时间 2010年5月 英 文 Responsive Web design 解 释 一个网站能够兼容多个终端 目 的 解决移动互联网的浏览 优 点 ...
- Linux下crontab命令的用法
cron来源于希腊单词chronos(意为“时间”),是linux系统下一个自动执行指定任务的程序.例如,你想在每晚睡觉期间创建某些文件或文件夹的备份,就可以用cron来自动执行. 服务的启动和停止 ...
- ethtool 命令详解
命令描述: ethtool 是用于查询及设置网卡参数的命令. 使用概要:ethtool ethx //查询ethx网口基本设置,其中 x 是对应网卡的编号,如eth0.eth1等等 转自: ...
- mysql lower,upper实现大小写
mysql的lower和uppper函数可以将指定字符串转换为小写和大写 select lower('OutSpringTd') as lowerCase, upper('OutSpringTd') ...
- #define 的一些用法 以及 迭代器的 [] 与 find()函数的区别
#include "stdafx.h" #include <map> #include <string> #include <iostream> ...
- iOS UIDatePicker frame改变问题
这种方法不行: pickerCtl = UIDatePicker(frame:pickerFrame) 但是这种却行 pickerCtl = UIDatePicker() pickerCtl!.fra ...
- BFS:Meteor Shower(POJ 3669)
奔跑吧,傻牛 题目大意:这只Bessie的牛又要来闹事了,这次她的任务就是来躲流星雨,流星雨就是在一定时间会从天上砸到Bessie的所在的正方形区域内(Bessie在0,0的位置),然后砸下 ...
- Intellij Idea无法从Controller跳转到视图页面的解决方案
解决方案: 第一步,确认配置了Spring支持,如下图: 一般情况下,配置完上面就可以正常导航了,但是今天要说的不是一般情况,否则也就不说了,如果经过第一步设置后,还是不能正常导航的同学,可以接着看第 ...
- 51nod 1264 线段相交
题目:传送门. 题意:给两条线段,有一个公共点或有部分重合认为相交,问他们是否相交. 题解:这属于非规范相交的情况,模板题. #include <iostream> #include &l ...