就是打个翻转标记,下推标记时记得交换左右孩子指针,查询kth和中序遍历输出时也记得要下推标记同时交换指针,二者不可缺!←这是易错点

仿陈竞潇学长模板的代码:

  1. #include<cctype>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. using namespace std;
  6. struct node{
  7. node();
  8. node *ch[2],*fa;
  9. short reversal;
  10. short pl(){return this==fa->ch[1];}
  11. int d,sum;
  12. void push(); void count();
  13. }*null;
  14. int N,M;
  15. node::node(){ch[0]=ch[1]=fa=null;reversal=sum=d=0;}
  16. void node::push(){
  17. if (this==null) return;
  18. if (reversal==1){
  19. reversal=0;
  20. ch[0]->reversal^=1;
  21. ch[1]->reversal^=1;
  22. node *k=ch[0];
  23. ch[0]=ch[1];
  24. ch[1]=k;
  25. }
  26. }
  27. void node::count(){
  28. sum=ch[0]->sum+ch[1]->sum+1;
  29. }
  30. namespace Splay{
  31. node *ROOT;
  32. node *build(int l=1,int r=N){
  33. if (l>r) return null;
  34. int mid=(l+r)>>1;
  35. node *ro=new node;
  36. ro->d=mid;
  37. ro->ch[0]=build(l,mid-1);
  38. ro->ch[1]=build(mid+1,r);
  39. ro->ch[0]->fa=ro;
  40. ro->ch[1]->fa=ro;
  41. ro->count();
  42. return ro;
  43. }
  44. void Build(){
  45. null=new node;
  46. *null=node();
  47. ROOT=build();
  48. ROOT->count();
  49. }
  50. void rotate(node *k){
  51. node *r=k->fa; if (r==null||k==null) return;
  52. r->push(); k->push();
  53. int x=k->pl()^1;
  54. r->ch[x^1]=k->ch[x];
  55. r->ch[x^1]->fa=r;
  56. if (r->fa==null) ROOT=k;
  57. else r->fa->ch[r->pl()]=k;
  58. k->fa=r->fa;
  59. r->fa=k;
  60. k->ch[x]=r;
  61. r->count(); k->count();
  62. }
  63. void splay(node *r,node *tar=null){
  64. for (;r->fa!=tar;rotate(r))
  65. if (r->fa->fa!=tar)rotate(r->pl()==r->fa->pl()?r->fa:r);
  66. r->push();
  67. }
  68. node *kth(int x){
  69. node *r=ROOT;
  70. while (r!=null){
  71. r->push();
  72. if (r->ch[0]->sum>=x) r=r->ch[0];
  73. else if (r->ch[0]->sum+1>=x) return r;
  74. else x-=r->ch[0]->sum+1,r=r->ch[1];
  75. }return null;
  76. }
  77. void rollingover(int ll,int rr){
  78. node *ln=kth(ll-1),*rn=kth(rr+1),*r;
  79. if ((ln==null)&&(rn==null)) r=ROOT;
  80. else if (ln==null){
  81. splay(rn); r=ROOT->ch[0];
  82. }else if (rn==null){
  83. splay(ln); r=ROOT->ch[1];
  84. }else{
  85. splay(ln); splay(rn,ROOT);
  86. r=ROOT->ch[1]->ch[0];
  87. }r->reversal=r->reversal^1;
  88. }
  89. void AC(node *r=ROOT){
  90. if (r==null) return;
  91. r->push();
  92. AC(r->ch[0]);
  93. printf("%d ",r->d);
  94. AC(r->ch[1]);
  95. }
  96. }
  97. int getint()
  98. {
  99. char c;
  100. while (!isdigit(c=getchar()));
  101. int a=c-'0';
  102. while (isdigit(c=getchar()))
  103. a=a*10+c-'0';
  104. return a;
  105. }
  106. int main()
  107. {
  108. N=getint();M=getint();
  109. Splay::Build();
  110. while (M--){
  111. int l=getint(),r=getint();
  112. Splay::rollingover(l,r);
  113. }
  114. Splay::AC();
  115. return 0;
  116. }

自己写的62行简洁代码:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #define read(x) x=getint()
  4. using namespace std;
  5. 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;}
  6. struct node{
  7. node();
  8. node *fa,*ch[2];
  9. int d,sum;
  10. bool rev;
  11. bool pl() {return this->fa->ch[1]==this;}
  12. void setc(node *r,bool c) {r->fa=this; this->ch[c]=r;}
  13. void push() {if (rev){swap(ch[0],ch[1]);ch[0]->rev^=1;ch[1]->rev^=1;rev=0;}}
  14. void count() {sum=ch[0]->sum+ch[1]->sum+1;}
  15. }*ROOT,*null;
  16. node::node(){fa=ch[0]=ch[1]=null;d=sum=rev=0;}
  17. int n,m;
  18. inline node *build(int l,int r){
  19. if (l>r) return null; int mid=(l+r)>>1; node *k=new node;
  20. k->ch[0]=build(l,mid-1); k->ch[1]=build(mid+1,r);
  21. if (k->ch[0]!=null) k->ch[0]->fa=k; if (k->ch[1]!=null) k->ch[1]->fa=k;
  22. k->d=mid; k->count(); return k;
  23. }
  24. inline void Build() {null=new node;*null=node();ROOT=build(1,n);}
  25. inline void rotate(node *r){
  26. node *f=r->fa; bool c=r->pl();
  27. if (f!=ROOT) f->fa->setc(r,f->pl());
  28. else r->fa=null,ROOT=r;
  29. f->setc(r->ch[!c],c); r->setc(f,!c);
  30. f->count();
  31. }
  32. inline void update(node *r) {if (r!=null) update(r->fa); r->push();}
  33. inline void splay(node *r,node *tar=null){
  34. update(r);
  35. for(;r->fa!=tar;rotate(r)) if (r->fa->fa!=tar) rotate(r->fa->pl()==r->pl()?r->fa:r);
  36. r->count();
  37. }
  38. inline node *kth(int x){
  39. if ((x==0)||(x==n+1)) return null;
  40. node *r=ROOT;
  41. while (1){
  42. r->push();
  43. if (r->ch[0]->sum>=x) r=r->ch[0];
  44. else if (r->ch[0]->sum+1>=x) return r;
  45. else {x-=r->ch[0]->sum+1; r=r->ch[1];}
  46. }
  47. }
  48. inline void reversal(int l,int r){
  49. node *ll=kth(l-1),*rr=kth(r+1);
  50. if ((ll==null)&&(rr==null)) ROOT->rev^=1;
  51. else if (ll==null) splay(rr),ROOT->ch[0]->rev^=1;
  52. else if (rr==null) splay(ll),ROOT->ch[1]->rev^=1;
  53. else splay(ll),splay(rr,ROOT),rr->ch[0]->rev^=1;
  54. }
  55. inline void AC(node *r) {if (r==null) return; r->push(); AC(r->ch[0]); printf("%d ",r->d); AC(r->ch[1]);}
  56. int main(){
  57. read(n); read(m); Build();
  58. int l,r;
  59. while (m--) {read(l); read(r); reversal(l,r);}
  60. AC(ROOT);
  61. return 0;
  62. }

然后就可以了

【BZOJ 3223】文艺平衡树 模板题的更多相关文章

  1. [题解]bzoj 3223 文艺平衡树

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3884  Solved: 2235[Submit][Sta ...

  2. bzoj 3223 文艺平衡树 - Splay

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3884  Solved: 2235[Submit][Sta ...

  3. BZOJ 3223 文艺平衡树 [codevs3303翻转区间]

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3223 通道2:http://codevs.cn/problem/3303/ 题目分析: 我 ...

  4. BZOJ 3223 文艺平衡树

    Description   您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2  ...

  5. bzoj 3223 文艺平衡树 splay 区间翻转

    Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 17715  Solved: 7769[Submit][Status][ ...

  6. bzoj 3223 文艺平衡树 Splay 打标志

    是NOI2003Editor的一个子任务 #include <cstdio> #include <vector> #define maxn 100010 using names ...

  7. 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 ...

  8. [bzoj3224]普通平衡树/3223文艺平衡树

    这是一道很普通的题.. 最近花了很多时间来想要去干什么,感觉自己还是太拿衣服 做这道题是因为偶尔看到了lavender的blog和她的bzoj早期AC记录,就被题目深深地吸引到了,原因有二: 自己sp ...

  9. BZOJ 2724 蒲公英 | 分块模板题

    题意 给出一个序列,在线询问区间众数.如果众数有多个,输出最小的那个. 题解 这是一道分块模板题. 一个询问的区间的众数,可能是中间"整块"区间的众数,也可能是左右两侧零散的数中的 ...

随机推荐

  1. DP+单调队列 codevs 1748 瑰丽华尔兹(还不是很懂具体的代码实现)

    codevs 1748 瑰丽华尔兹 2005年NOI全国竞赛  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master 题解       题目描述 Descripti ...

  2. 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 ...

  3. [cocos2dx]2.2到3.1(3.0)升级帮助

    摘要: cocos2dx 是一款优秀的多平台,专为2D游戏设计的引擎. 在活跃的开源社区的推进下, 越发稳定和强大. 2.x -> 3.x的更新幅度很大, 性能的提升和功能的丰富也非常明显. 但 ...

  4. redis 一二事 - 搭建集群缓存服务器

    在如今并发的环境下,对大数据量的查询采用缓存是最好不过的了,本文使用redis搭建集群 (个人喜欢redis,对memcache不感冒) redis是3.0后增加的集群功能,非常强大 集群中应该至少有 ...

  5. Jedis下的ShardedJedis(分布式)使用方法(二)

    上一篇中介绍了ShardedJedis的基本使用方法以及演示了一个简单的例子,在这一篇中我们来介绍了ShardedJedis的原理. 1.ShardedJedis内部实现 首先我们来看一下Sharde ...

  6. Vernam密码

    Vernam加密法也称一次一密(One-Time-Pad),用随机的非重复的字符集合作为输出密文.这里最重要的是,一旦使用了变换的输入密文,就不再在任何其他消息中使用这个输入密文(因此是一次性的).输 ...

  7. memcached缓存知识简单梳理

    memcached工作原理基本概念:slab,page,chunk.slab,是一个逻辑概念.它是在启动memcached实例的时候预处理好的,每个slab对应一个chunk size,也就是说不同s ...

  8. heartbeat初探

    1,概念及原理 http://www.mingxiao.info/tag/heartbeat/

  9. JS 禁用和重新启用a标签的点击事件

    function changeHomePageModule(){ var css = $('#collapseExample').attr('class'); if(css=='collapse'){ ...

  10. Linux常用指令---find | locate(查找)

    1.locate locate指令和find找寻档案的功能类似,但locate是透过update程序将硬盘中的所有档案和目录资料先建立一个索引数据库,在 执行loacte时直接找该索引,查询速度会较快 ...