【BZOJ 3223】文艺平衡树 模板题
就是打个翻转标记,下推标记时记得交换左右孩子指针,查询kth和中序遍历输出时也记得要下推标记同时交换指针,二者不可缺!←这是易错点
仿陈竞潇学长模板的代码:
- #include<cctype>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- struct node{
- node();
- node *ch[2],*fa;
- short reversal;
- short pl(){return this==fa->ch[1];}
- int d,sum;
- void push(); void count();
- }*null;
- int N,M;
- node::node(){ch[0]=ch[1]=fa=null;reversal=sum=d=0;}
- void node::push(){
- if (this==null) return;
- if (reversal==1){
- reversal=0;
- ch[0]->reversal^=1;
- ch[1]->reversal^=1;
- node *k=ch[0];
- ch[0]=ch[1];
- ch[1]=k;
- }
- }
- void node::count(){
- sum=ch[0]->sum+ch[1]->sum+1;
- }
- namespace Splay{
- node *ROOT;
- node *build(int l=1,int r=N){
- if (l>r) return null;
- int mid=(l+r)>>1;
- node *ro=new node;
- ro->d=mid;
- ro->ch[0]=build(l,mid-1);
- ro->ch[1]=build(mid+1,r);
- ro->ch[0]->fa=ro;
- ro->ch[1]->fa=ro;
- ro->count();
- return ro;
- }
- void Build(){
- null=new node;
- *null=node();
- ROOT=build();
- ROOT->count();
- }
- void rotate(node *k){
- node *r=k->fa; if (r==null||k==null) return;
- r->push(); k->push();
- int x=k->pl()^1;
- r->ch[x^1]=k->ch[x];
- r->ch[x^1]->fa=r;
- if (r->fa==null) ROOT=k;
- else r->fa->ch[r->pl()]=k;
- k->fa=r->fa;
- r->fa=k;
- k->ch[x]=r;
- r->count(); k->count();
- }
- void splay(node *r,node *tar=null){
- for (;r->fa!=tar;rotate(r))
- if (r->fa->fa!=tar)rotate(r->pl()==r->fa->pl()?r->fa:r);
- r->push();
- }
- node *kth(int x){
- node *r=ROOT;
- while (r!=null){
- r->push();
- if (r->ch[0]->sum>=x) r=r->ch[0];
- else if (r->ch[0]->sum+1>=x) return r;
- else x-=r->ch[0]->sum+1,r=r->ch[1];
- }return null;
- }
- void rollingover(int ll,int rr){
- node *ln=kth(ll-1),*rn=kth(rr+1),*r;
- if ((ln==null)&&(rn==null)) r=ROOT;
- else if (ln==null){
- splay(rn); r=ROOT->ch[0];
- }else if (rn==null){
- splay(ln); r=ROOT->ch[1];
- }else{
- splay(ln); splay(rn,ROOT);
- r=ROOT->ch[1]->ch[0];
- }r->reversal=r->reversal^1;
- }
- void AC(node *r=ROOT){
- if (r==null) return;
- r->push();
- AC(r->ch[0]);
- printf("%d ",r->d);
- AC(r->ch[1]);
- }
- }
- int getint()
- {
- char c;
- while (!isdigit(c=getchar()));
- int a=c-'0';
- while (isdigit(c=getchar()))
- a=a*10+c-'0';
- return a;
- }
- int main()
- {
- N=getint();M=getint();
- Splay::Build();
- while (M--){
- int l=getint(),r=getint();
- Splay::rollingover(l,r);
- }
- Splay::AC();
- return 0;
- }
自己写的62行简洁代码:
- #include<cstdio>
- #include<algorithm>
- #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;}
- struct node{
- node();
- node *fa,*ch[2];
- int d,sum;
- bool rev;
- bool pl() {return this->fa->ch[1]==this;}
- void setc(node *r,bool c) {r->fa=this; this->ch[c]=r;}
- void push() {if (rev){swap(ch[0],ch[1]);ch[0]->rev^=1;ch[1]->rev^=1;rev=0;}}
- void count() {sum=ch[0]->sum+ch[1]->sum+1;}
- }*ROOT,*null;
- node::node(){fa=ch[0]=ch[1]=null;d=sum=rev=0;}
- int n,m;
- inline node *build(int l,int r){
- if (l>r) return null; int mid=(l+r)>>1; node *k=new node;
- k->ch[0]=build(l,mid-1); k->ch[1]=build(mid+1,r);
- if (k->ch[0]!=null) k->ch[0]->fa=k; if (k->ch[1]!=null) k->ch[1]->fa=k;
- k->d=mid; k->count(); return k;
- }
- inline void Build() {null=new node;*null=node();ROOT=build(1,n);}
- inline void rotate(node *r){
- node *f=r->fa; bool c=r->pl();
- if (f!=ROOT) f->fa->setc(r,f->pl());
- else r->fa=null,ROOT=r;
- f->setc(r->ch[!c],c); r->setc(f,!c);
- f->count();
- }
- inline void update(node *r) {if (r!=null) update(r->fa); r->push();}
- inline void splay(node *r,node *tar=null){
- update(r);
- for(;r->fa!=tar;rotate(r)) if (r->fa->fa!=tar) rotate(r->fa->pl()==r->pl()?r->fa:r);
- r->count();
- }
- inline node *kth(int x){
- if ((x==0)||(x==n+1)) return null;
- node *r=ROOT;
- while (1){
- r->push();
- if (r->ch[0]->sum>=x) r=r->ch[0];
- else if (r->ch[0]->sum+1>=x) return r;
- else {x-=r->ch[0]->sum+1; r=r->ch[1];}
- }
- }
- inline void reversal(int l,int r){
- node *ll=kth(l-1),*rr=kth(r+1);
- if ((ll==null)&&(rr==null)) ROOT->rev^=1;
- else if (ll==null) splay(rr),ROOT->ch[0]->rev^=1;
- else if (rr==null) splay(ll),ROOT->ch[1]->rev^=1;
- else splay(ll),splay(rr,ROOT),rr->ch[0]->rev^=1;
- }
- inline void AC(node *r) {if (r==null) return; r->push(); AC(r->ch[0]); printf("%d ",r->d); AC(r->ch[1]);}
- int main(){
- read(n); read(m); Build();
- int l,r;
- while (m--) {read(l); read(r); reversal(l,r);}
- AC(ROOT);
- return 0;
- }
然后就可以了
【BZOJ 3223】文艺平衡树 模板题的更多相关文章
- [题解]bzoj 3223 文艺平衡树
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3884 Solved: 2235[Submit][Sta ...
- bzoj 3223 文艺平衡树 - Splay
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3884 Solved: 2235[Submit][Sta ...
- BZOJ 3223 文艺平衡树 [codevs3303翻转区间]
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3223 通道2:http://codevs.cn/problem/3303/ 题目分析: 我 ...
- BZOJ 3223 文艺平衡树
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 ...
- bzoj 3223 文艺平衡树 splay 区间翻转
Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 17715 Solved: 7769[Submit][Status][ ...
- bzoj 3223 文艺平衡树 Splay 打标志
是NOI2003Editor的一个子任务 #include <cstdio> #include <vector> #define maxn 100010 using names ...
- HDU 4006 The kth great number 优先队列、平衡树模板题(SBT)
The kth great number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Oth ...
- [bzoj3224]普通平衡树/3223文艺平衡树
这是一道很普通的题.. 最近花了很多时间来想要去干什么,感觉自己还是太拿衣服 做这道题是因为偶尔看到了lavender的blog和她的bzoj早期AC记录,就被题目深深地吸引到了,原因有二: 自己sp ...
- BZOJ 2724 蒲公英 | 分块模板题
题意 给出一个序列,在线询问区间众数.如果众数有多个,输出最小的那个. 题解 这是一道分块模板题. 一个询问的区间的众数,可能是中间"整块"区间的众数,也可能是左右两侧零散的数中的 ...
随机推荐
- DP+单调队列 codevs 1748 瑰丽华尔兹(还不是很懂具体的代码实现)
codevs 1748 瑰丽华尔兹 2005年NOI全国竞赛 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 Descripti ...
- 06-图2 Saving James Bond - Easy Version
题目来源:http://pta.patest.cn/pta/test/18/exam/4/question/625 This time let us consider the situation in ...
- [cocos2dx]2.2到3.1(3.0)升级帮助
摘要: cocos2dx 是一款优秀的多平台,专为2D游戏设计的引擎. 在活跃的开源社区的推进下, 越发稳定和强大. 2.x -> 3.x的更新幅度很大, 性能的提升和功能的丰富也非常明显. 但 ...
- redis 一二事 - 搭建集群缓存服务器
在如今并发的环境下,对大数据量的查询采用缓存是最好不过的了,本文使用redis搭建集群 (个人喜欢redis,对memcache不感冒) redis是3.0后增加的集群功能,非常强大 集群中应该至少有 ...
- Jedis下的ShardedJedis(分布式)使用方法(二)
上一篇中介绍了ShardedJedis的基本使用方法以及演示了一个简单的例子,在这一篇中我们来介绍了ShardedJedis的原理. 1.ShardedJedis内部实现 首先我们来看一下Sharde ...
- Vernam密码
Vernam加密法也称一次一密(One-Time-Pad),用随机的非重复的字符集合作为输出密文.这里最重要的是,一旦使用了变换的输入密文,就不再在任何其他消息中使用这个输入密文(因此是一次性的).输 ...
- memcached缓存知识简单梳理
memcached工作原理基本概念:slab,page,chunk.slab,是一个逻辑概念.它是在启动memcached实例的时候预处理好的,每个slab对应一个chunk size,也就是说不同s ...
- heartbeat初探
1,概念及原理 http://www.mingxiao.info/tag/heartbeat/
- JS 禁用和重新启用a标签的点击事件
function changeHomePageModule(){ var css = $('#collapseExample').attr('class'); if(css=='collapse'){ ...
- Linux常用指令---find | locate(查找)
1.locate locate指令和find找寻档案的功能类似,但locate是透过update程序将硬盘中的所有档案和目录资料先建立一个索引数据库,在 执行loacte时直接找该索引,查询速度会较快 ...