其实就是一道题占坑啦

[NOI2005]维护数列

分析:

每次操作都要 \(Splay\) 一下

\(Insert\) 操作:重建一棵平衡树,把 \(l\) 变成根,\(l+2\) 变成右子树的根,那棵平衡树就挂在 \(l+2\) 的左子树下

\(Delete\) 操作:直接将其左子树删掉

\(Make-Same\) 操作:把整个区间打一个标记,每次 \(pushdown\) 就好了

\(Reverse\) 操作:类似 \(Make-Same\) 操作

\(Get-Sum\) 操作:直接输出 \(sum\)

\(Max-Sum\) 操作:记 \(Max,lmax,rmax\),每次 \(pushup\) 和 \(pushdown\) 的时候弄一下就好了

\(Code\ Below:\)

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=6000000+10;
  4. const int inf=0x3f3f3f3f;
  5. int n,m,a[maxn],ch[maxn][2],fa[maxn],key[maxn],siz[maxn],sum[maxn],Max[maxn],lmax[maxn],rmax[maxn],rt,sz;
  6. bool rev[maxn],tag[maxn];
  7. inline int read(){
  8. register int x=0,f=1;char ch=getchar();
  9. while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
  10. while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
  11. return (f==1)?x:-x;
  12. }
  13. inline void pushup(int x){
  14. siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
  15. sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+key[x];
  16. Max[x]=max(rmax[ch[x][0]]+key[x]+lmax[ch[x][1]],max(Max[ch[x][0]],Max[ch[x][1]]));
  17. lmax[x]=max(lmax[ch[x][0]],sum[ch[x][0]]+key[x]+lmax[ch[x][1]]);
  18. rmax[x]=max(rmax[ch[x][1]],rmax[ch[x][0]]+key[x]+sum[ch[x][1]]);
  19. }
  20. inline void pushdown(int x){
  21. if(tag[x]){
  22. key[ch[x][0]]=key[ch[x][1]]=key[x];
  23. sum[ch[x][0]]=siz[ch[x][0]]*key[x];
  24. sum[ch[x][1]]=siz[ch[x][1]]*key[x];
  25. if(ch[x][0]) Max[ch[x][0]]=max(key[x],sum[ch[x][0]]);
  26. if(ch[x][1]) Max[ch[x][1]]=max(key[x],sum[ch[x][1]]);
  27. lmax[ch[x][0]]=rmax[ch[x][0]]=max(0,sum[ch[x][0]]);
  28. lmax[ch[x][1]]=rmax[ch[x][1]]=max(0,sum[ch[x][1]]);
  29. tag[ch[x][0]]=tag[ch[x][1]]=1;tag[x]=rev[x]=0;
  30. }
  31. if(rev[x]){
  32. swap(lmax[ch[x][0]],rmax[ch[x][0]]);
  33. swap(lmax[ch[x][1]],rmax[ch[x][1]]);
  34. swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
  35. swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
  36. rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;rev[x]=0;
  37. }
  38. }
  39. inline void rotate(int x){
  40. int y=fa[x],z=fa[y],k=(x==ch[y][1]);
  41. ch[y][k]=ch[x][k^1];fa[ch[x][k^1]]=y;
  42. ch[x][k^1]=y;fa[y]=x;fa[x]=z;
  43. if(z) ch[z][ch[z][1]==y]=x;
  44. pushup(y);pushup(x);
  45. }
  46. inline void splay(int x,int z){
  47. for(int y;(y=fa[x])!=z;rotate(x))
  48. if(fa[y]!=z) rotate((x==ch[y][1])^(y==ch[z][1])?x:y);
  49. if(!z) rt=x;
  50. }
  51. inline int findkth(int x,int k){
  52. while(1){
  53. pushdown(x);
  54. if(k<=siz[ch[x][0]]) x=ch[x][0];
  55. else {
  56. k-=siz[ch[x][0]]+1;
  57. if(!k) return x;
  58. x=ch[x][1];
  59. }
  60. }
  61. }
  62. inline int split(int l,int r){
  63. l=findkth(rt,l);r=findkth(rt,r);
  64. splay(l,0);splay(r,l);
  65. return ch[r][0];
  66. }
  67. inline int query(int l,int r){
  68. return sum[split(l,r)];
  69. }
  70. inline void modify(int l,int r,int v){
  71. int x=split(l,r),y=fa[x],z=fa[y];
  72. key[x]=v;tag[x]=1;sum[x]=siz[x]*key[x];
  73. Max[x]=max(key[x],sum[x]);
  74. lmax[x]=rmax[x]=max(0,sum[x]);
  75. pushup(y);pushup(z);
  76. }
  77. inline void reverse(int l,int r){
  78. int x=split(l,r),y=fa[x],z=fa[y];
  79. if(!tag[x]){
  80. rev[x]^=1;
  81. swap(lmax[x],rmax[x]);
  82. swap(ch[x][0],ch[x][1]);
  83. pushup(y);pushup(z);
  84. }
  85. }
  86. inline void erase(int l,int r){
  87. int x=split(l,r),y=fa[x],z=fa[y];
  88. ch[y][0]=0;pushup(y);pushup(z);
  89. }
  90. int build(int l,int r,int f){
  91. int mid=(l+r)>>1,x=++sz;
  92. if(l==r){
  93. siz[x]=1;sum[x]=Max[x]=a[l];
  94. lmax[x]=rmax[x]=max(0,a[l]);
  95. }
  96. if(l<mid) ch[x][0]=build(l,mid-1,x);
  97. if(mid<r) ch[x][1]=build(mid+1,r,x);
  98. key[x]=a[mid];fa[x]=f;pushup(x);
  99. return x;
  100. }
  101. inline void insert(int l,int r){
  102. for(int i=1;i<=r;i++) a[i]=read();
  103. int z=build(1,r,0),x=findkth(rt,l+1),y=findkth(rt,l+2);
  104. splay(x,0);splay(y,x);
  105. fa[z]=y;ch[y][0]=z;
  106. pushup(y);pushup(x);
  107. }
  108. int main()
  109. {
  110. n=read(),m=read();
  111. Max[0]=a[1]=a[n+2]=-inf;
  112. for(int i=2;i<=n+1;i++) a[i]=read();
  113. rt=build(1,n+2,0);
  114. char op[20];int pos,tot,val;
  115. while(m--){
  116. scanf("%s",op);
  117. if(op[0]=='I'){
  118. pos=read(),tot=read();
  119. insert(pos,tot);
  120. }
  121. if(op[0]=='D'){
  122. pos=read(),tot=read();
  123. erase(pos,pos+tot+1);
  124. }
  125. if(op[0]=='M'){
  126. if(op[2]=='K'){
  127. pos=read(),tot=read(),val=read();
  128. modify(pos,pos+tot+1,val);
  129. }
  130. else printf("%d\n",Max[rt]);
  131. }
  132. if(op[0]=='R'){
  133. pos=read(),tot=read();
  134. reverse(pos,pos+tot+1);
  135. }
  136. if(op[0]=='G'){
  137. pos=read(),tot=read();
  138. printf("%d\n",query(pos,pos+tot+1));
  139. }
  140. }
  141. return 0;
  142. }

[学习笔记]Splay的更多相关文章

  1. [学习笔记] Splay Tree 从入门到放弃

    前几天由于出行计划没有更博QwQ (其实是因为调试死活调不出来了TAT我好菜啊) 伸展树 伸展树(英语:Splay Tree)是一种二叉查找树,它能在O(log n)内完成插入.查找和删除操作.它是由 ...

  2. 平衡树splay学习笔记#2

    讲一下另外的所有操作(指的是普通平衡树中的其他操作) 前一篇的学习笔记连接:[传送门],结尾会带上完整的代码. 操作1,pushup操作 之前学习过线段树,都知道子节点的信息需要更新到父亲节点上. 因 ...

  3. [学习笔记]平衡树(Splay)——旋转的灵魂舞蹈家

    1.简介 首先要知道什么是二叉查找树. 这是一棵二叉树,每个节点最多有一个左儿子,一个右儿子. 它能支持查找功能. 具体来说,每个儿子有一个权值,保证一个节点的左儿子权值小于这个节点,右儿子权值大于这 ...

  4. 平衡树学习笔记(3)-------Splay

    Splay 上一篇:平衡树学习笔记(2)-------Treap Splay是一个实用而且灵活性很强的平衡树 效率上也比较客观,但是一定要一次性写对 debug可能不是那么容易 Splay作为平衡树, ...

  5. BST,Splay平衡树学习笔记

    BST,Splay平衡树学习笔记 1.二叉查找树BST BST是一种二叉树形结构,其特点就在于:每一个非叶子结点的值都大于他的左子树中的任意一个值,并都小于他的右子树中的任意一个值. 2.BST的用处 ...

  6. 学习笔记 | CDQ分治

    目录 前言 啥是CDQ啊(它的基本思想) 例题 后记 参考博文 前言 博主太菜了 学习快一年的OI了 好像没有什么会的算法 更寒碜的是 学一样还不精一样TAT 如有什么错误请各位路过的大佬指出啊感谢! ...

  7. OI知识点|NOIP考点|省选考点|教程与学习笔记合集

    点亮技能树行动-- 本篇blog按照分类将网上写的OI知识点归纳了一下,然后会附上蒟蒻我的学习笔记或者是我认为写的不错的专题博客qwqwqwq(好吧,其实已经咕咕咕了...) 基础算法 贪心 枚举 分 ...

  8. 平衡树学习笔记(6)-------RBT

    RBT 上一篇:平衡树学习笔记(5)-------SBT RBT是...是一棵恐怖的树 有多恐怖? 平衡树中最快的♂ 不到200ms的优势,连权值线段树都无法匹敌 但是,通过大量百度,发现RBT的代码 ...

  9. 平衡树学习笔记(5)-------SBT

    SBT 上一篇:平衡树学习笔记(4)-------替罪羊树 所谓SBT,就是Size Balanced Tree 它的速度很快,完全碾爆Treap,Splay等平衡树,而且代码简洁易懂 尤其是插入节点 ...

随机推荐

  1. hadoop报错:java.io.IOException(java.net.ConnectException: Call From xxx/xxx to xxx:10020 failed on connection exception: java.net.ConnectException: 拒绝连接

    任务一直报错 现象比较奇怪,部分任务可以正常跑,部分问题报错 报错信息如下: Ended Job = job_1527476268558_132947 with exception 'java.io. ...

  2. react创建项目报错unexpected end of json while parsing near xxx

    报这个错,执行下面的命令,然后重新创建项目就可以. npm cache clean --force

  3. aliyun API 调试

    打开https://ai.aliyun.com/,登录阿里云账号,选择控制台,右侧标签中选择产品服务,选择自己需要的子标签(如图像识别),选择API调试,按要求填写表格. 其中请求Body参照API文 ...

  4. python3 提示 name ‘reload’ is not defined

    import importlib importlib.reload(sys)

  5. 剑指offer42:不用加减乘除做加法

    分析: (1)十进制加法分三步:(以5+17=22为例) 1. 只做各位相加不进位,此时相加结果为12(个位数5和7相加不进位是2,十位数0和1相加结果是1): 2. 做进位,5+7中有进位,进位的值 ...

  6. Kindeditor图片粘贴上传(chrome)

    kindeditor4.1.x版本已支持图片批量上传,不过传统的选文件上传的方式依然效率低下. 很多时候,编辑人员可能需要将一个文档中图片上传到网上,那么,按照传统的上传方法,他必须先将图片另存为到本 ...

  7. 《ARM Cortex-M3权威指南》笔记(1)

    http://blog.csdn.net/roverx/article/details/6624859 第1章 介绍 一.ARM Cortex‐M3处理器初探 CM3处理器内核是单片机的中央处理单元( ...

  8. SSM_CRUD新手练习(6)分页后台控制器编写

    经过测试基础环境已经搭建好了,现在我们开始编写CRUD. 我们来看一下查询的逻辑该怎么写: 1.访问index.jsp页面 2.index.jsp页面发送查询员工的请求 3.EmployeeContr ...

  9. noip第5课作业

    1.     计算税收 [问题描述] 对某产品征收税金,在产值1万元以上收税5%:在1万元以下但在5000元或者以上的征收税3%:在5000元以下但在1000元或以上征收税2%:1000元以下的免收税 ...

  10. 13.1.DataGrid的增、删、改、查前台页面

    公共js: 前台页面: