插入操作,删除操作和置换操作都是单点的,所以不需要lazy标记。这个很简单,都是两次RotateTo,一次Splay操作就搞定。

求最大连续字段和的操作和线段树的题目类似,只需要保存最左边的连续最大字段和,最右边的连续最大字段和,整个子树的连续最大字段和就OK,整个子树的和就OK。

注意PushUp函数的写法就OK

//Problem Specific Function
void PushUp(int x )
{
int ll = sp[x].child[0], rr = sp[x].child[1];
// sz, lsum , rsum , msum, sum
sp[x].sz = 1 + sp[sp[x].child[0]].sz + sp[sp[x].child[1]].sz;
sp[x].sum = sp[x].val + sp[sp[x].child[0]].sum + sp[sp[x].child[1]].sum;
sp[x].lsum = max(sp[ll].lsum, sp[ll].sum + sp[x].val + max(sp[rr].lsum, 0));
sp[x].rsum = max(sp[rr].rsum, sp[rr].sum + sp[x].val + max(sp[ll].rsum , 0));
// 这里类似于线段树的
sp[x].msum = max(max(sp[ll].msum, sp[rr].msum), sp[x].val + max(sp[ll].rsum, 0) + max(sp[rr].lsum, 0));
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

这个题目的代码

   1:   
   2:  #include <cstdio>
   3:  #include <iostream>
   4:   
   5:  using namespace std;
   6:  #define INF 10009
   7:  #define MaxL 222222
   8:  #define keyTree   sp[sp[root].child[1]].child[0]
   9:   
  10:  struct SplayTreeNode
  11:  {
  12:      int parent, child[2];   // parent and child[0] left child[1] right
  13:      int sz, val;  // sz 表示当前节点为根的子树总节点个数.  val表示当前节点的键值。
  14:      int sum;    // 以x为根节点的子树的所有的和
  15:      int lsum;   // 以该点为根的子树的左子树最大的连续和 [left, x)
  16:      int rsum;   // 以该点为根的子树的右子树 最大的连续和 (x, right]
  17:      int msum;   // 以该点为根的子树中的连续最大字段和
  18:  };
  19:   
  20:  int num[MaxL];
  21:  struct SpalyTree
  22:  {
  23:      SplayTreeNode sp[MaxL];   // save space
  24:      int gc[MaxL];   // Garbage Collection idx
  25:      int root;  // root idx
  26:      int idx;   // Forward allocate tree
  27:      int idxrev; // garbage allocated nodes used for next allocation priority
  28:   
  29:      /*
  30:           A                        B
  31:         /   \    R(B,RR)->       /   \
  32:        B     C    <-R(A,LL)     D     A
  33:       / \                            /  \
  34:      D   E                          E    C
  35:      */
  36:      void Rotate(int x,int f)   // f ==0 l rot,1 r rot
  37:      {
  38:          int y = sp[x].parent;
  39:          //PushDown(y);
  40:          //PushDown(x);
  41:          sp[y].child[!f] = sp[x].child[f];
  42:          sp[sp[x].child[f]].parent = y;
  43:          sp[x].parent = sp[y].parent;
  44:          if(sp[x].parent)
  45:              sp[sp[y].parent].child[ sp[sp[y].parent].child[1] == y]= x;
  46:          sp[x].child[f] = y;
  47:          sp[y].parent = x;
  48:          PushUp(y);
  49:      }
  50:   
  51:      void Splay(int x, int goal)
  52:      {
  53:          //PushDown(x);
  54:          while(sp[x].parent != goal)
  55:          {
  56:              if(sp[sp[x].parent].parent == goal)
  57:                  Rotate(x, sp[sp[x].parent].child[0] == x);
  58:              else
  59:              {
  60:                  int y = sp[x].parent, z = sp[y].parent;
  61:                  int f = sp[z].child[0] == y;
  62:                  if(sp[y].child[f] == x)
  63:                      Rotate(x,!f), Rotate(x,f);
  64:                  else
  65:                      Rotate(y,f), Rotate(x,f);
  66:   
  67:              }
  68:          }
  69:          PushUp(x);
  70:          if(goal == 0) root = x;
  71:      }
  72:      //  把第k个的数转到goal下边,一般用来调整区间
  73:      int RotateTo(int k, int goal)
  74:      {
  75:          int x = root;
  76:          //PushDown(x);
  77:          while(sp[sp[x].child[0]].sz !=k)
  78:          {
  79:              if( k< sp [ sp[x].child[0] ].sz)
  80:                  x = sp[x].child[0];
  81:              else
  82:              {
  83:                  k -= sp[sp[x].child[0]].sz +1;
  84:                  x = sp[x].child[1];
  85:              }
  86:  //            PushDown(x);
  87:          }
  88:  //        cout<<"Rotate "<<x<<" goal "<<goal<<endl;
  89:          Splay(x, goal);
  90:          return x;
  91:      }
  92:   
  93:      void NewNode(int &x, int c)
  94:      {
  95:          if( idxrev) x = gc[--idxrev];
  96:          else  x = ++idx;
  97:          sp[x].child[1] = 0, sp[x].child[0] = 0, sp[x].parent = 0;
  98:          sp[x].sz = 1;
  99:          sp[x].val = sp[x].sum = sp[x].lsum = sp[x].rsum  = sp[x].msum = c;
 100:          //sp[x].lazy = 0;
 101:      }
 102:   
 103:      //把以x为祖先结点(x 也算)删掉放进内存池,回收内存
 104:      void eraseSubTree(int x)
 105:      {
 106:          int father = sp[x].parent;
 107:          int head = idxrev , tail = idxrev;
 108:          for (gc[tail++] = x ; head < tail ; head ++)
 109:          {
 110:              idxrev++;
 111:              if( sp[gc[head]].child[0]) gc[tail++] = sp[gc[head]].child[0];
 112:              if( sp[gc[head]].child[1]) gc[tail++] = sp[gc[head]].child[1];
 113:          }
 114:          sp[father].child[ sp[father].child[1] == x] = 0;
 115:          PushUp(father);
 116:      }
 117:   
 118:   
 119:      void makeTree(int &x, int l, int r, int parent)
 120:      {
 121:          if(l > r) return ;
 122:          int m = (l+r)>>1;
 123:          NewNode(x,num[m]);
 124:          makeTree(sp[x].child[0], l, m-1, x);
 125:          makeTree(sp[x].child[1], m+1, r, x);
 126:          sp[x].parent = parent;
 127:          PushUp(x);
 128:      }
 129:      void Init(int n)
 130:      {
 131:          idx = idxrev =  0;
 132:          root = 0;
 133:          sp[0].child[0] = sp[0].child[1] = sp[0].parent  = 0;
 134:          sp[0].sz = sp[0].sum = 0;
 135:          sp[0].val = sp[0].lsum = sp[0].rsum = sp[0].msum = -INF;
 136:          NewNode(root, -INF);
 137:          NewNode(sp[root].child[1], -INF);
 138:          sp[idx].parent = root;
 139:          sp[root].sz = 2;
 140:          makeTree( sp [sp[root].child[1] ].child[0] , 1, n, sp[root].child[1]);
 141:          PushUp(sp[root].child[1]);
 142:          PushUp(root);
 143:      }
 144:   
 145:      void Travel(int x)
 146:      {
 147:          if(x)
 148:          {
 149:              Travel( sp[x].child[0]);
 150:              printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d  sum = %2d\n",x, sp[x].child[0],sp[x].child[1],sp[x].parent,sp[x].sz,sp[x].val, sp[x].sum);
 151:              Travel( sp[x].child[1]);
 152:          }
 153:      }
 154:   
 155:      //Problem Specific Function
 156:      void PushUp(int x )
 157:      {
 158:          int ll = sp[x].child[0], rr = sp[x].child[1];
 159:          // sz, lsum , rsum , msum, sum
 160:          sp[x].sz = 1 + sp[sp[x].child[0]].sz + sp[sp[x].child[1]].sz;
 161:          sp[x].sum =  sp[x].val + sp[sp[x].child[0]].sum + sp[sp[x].child[1]].sum;
 162:          sp[x].lsum = max(sp[ll].lsum, sp[ll].sum + sp[x].val + max(sp[rr].lsum, 0));
 163:          sp[x].rsum = max(sp[rr].rsum, sp[rr].sum + sp[x].val + max(sp[ll].rsum , 0));
 164:          // 这里类似于线段树的
 165:          sp[x].msum = max(max(sp[ll].msum, sp[rr].msum), sp[x].val + max(sp[ll].rsum, 0) + max(sp[rr].lsum, 0));
 166:      }
 167:   
 168:      void Insert(int pos, int m)
 169:      {
 170:          RotateTo(pos - 1, 0);
 171:          RotateTo(pos, root);
 172:          int p = 0;
 173:          NewNode(p, m);
 174:          keyTree = p;
 175:          sp[p].parent = sp[root].child[1];
 176:          Splay(p,0);
 177:      }
 178:   
 179:      void Delete(int pos)
 180:      {
 181:          RotateTo(pos-1, 0);
 182:          RotateTo(pos+1, root);
 183:          eraseSubTree(keyTree);
 184:          Splay(sp[root].child[1], 0);
 185:      }
 186:   
 187:      void Replace(int pos, int m)
 188:      {
 189:          RotateTo(pos-1, 0);
 190:          RotateTo(pos+1, root);
 191:          int x = keyTree;
 192:          sp[x].val = sp[x].sum = sp[x].lsum = sp[x].rsum  = sp[x].msum = m;
 193:          Splay(keyTree,0);
 194:      }
 195:   
 196:      int Query(int l, int r)
 197:      {
 198:          RotateTo(l -1, 0);
 199:          RotateTo(r+1, root);
 200:   
 201:          int ret =  sp[keyTree].msum;
 202:          Splay(keyTree,0);
 203:          return ret;
 204:      }
 205:  } spt;
 206:   
 207:   
 208:  int main()
 209:  {
 210:  //    freopen("1.txt","r",stdin);
 211:      int n;
 212:      while(scanf("%d",&n)!=EOF)
 213:      {
 214:          for(int i=1; i<=n; i++)
 215:              scanf("%d",&num[i]);
 216:          spt.Init(n);
 217:          int q;
 218:          scanf("%d", &q);
 219:          while(q--)
 220:          {
 221:              char op[2];
 222:              scanf("%s",op);
 223:              int pos,m;
 224:              if(op[0]=='I')
 225:              {
 226:                  n++;
 227:                  scanf("%d%d",&pos, &m);
 228:                  spt.Insert(pos,m);
 229:              }
 230:              else if(op[0]=='D')
 231:              {
 232:                  n--;
 233:  //                scanf_(pos);
 234:                  scanf("%d", & pos);
 235:                  spt.Delete(pos);
 236:              }
 237:              else if(op[0]=='R')
 238:              {
 239:                  scanf("%d%d",&pos, &m);
 240:                  spt.Replace(pos,m);
 241:              }
 242:              else if(op[0]=='Q')
 243:              {
 244:                  scanf("%d%d", &pos, &m);
 245:                  printf("%d\n", spt.Query(pos,m));
 246:              }
 247:          }
 248:      }
 249:      return 0;
 250:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

SPOJ 4487 Splay 基本操作的更多相关文章

  1. spoj 4487. Can you answer these queries VI (gss6) splay 常数优化

    4487. Can you answer these queries VI Problem code: GSS6 Given a sequence A of N (N <= 100000) in ...

  2. SPOJ 4487. Can you answer these queries VI splay

    题目链接:点击打开链接 题意比較明显,不赘述. 删除时能够把i-1转到根,把i+1转到根下 则i点就在 根右子树 的左子树,且仅仅有i这一个 点 #include<stdio.h> #in ...

  3. Splay基本操作

    我们以一道题来引入吧! 传送门 题目说的很清楚,我们的数据结构要支持:插入x数,删除x数,查询数的排名和排名为x的数,求一个数前驱后继. 似乎用啥现有的数据结构都很难做到在O(nlogn)的复杂度中把 ...

  4. 【BZOJ-1552&3506】robotic sort&排序机械臂 Splay

    1552: [Cerc2007]robotic sort Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 806  Solved: 329[Submit][ ...

  5. splay详解(一)

    前言 Spaly是基于二叉查找树实现的, 什么是二叉查找树呢?就是一棵树呗:joy: ,但是这棵树满足性质—一个节点的左孩子一定比它小,右孩子一定比它大 比如说 这就是一棵最基本二叉查找树 对于每次插 ...

  6. splay:优雅的区间暴力!

    万年不更的blog主更新啦!主要是最近实在忙,好不容易才从划水做题的时间中抽出一段时间来写这篇blog 首先声明:这篇blog写的肯定会很基础...因为身为一个蒟蒻深知在茫茫大海中找到一个自己完全能够 ...

  7. POJ3468:A Simple Problem with Integers (线段树||树状数组||Splay解决基本问题的效率对比)

    You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of op ...

  8. Splay&LCT

    Splay && LCT \(\text{Splay}\) 基本操作 1.\(Zig \& Zag\) 其思想是维护中序遍历不变 实现中我们不真的用\(Zig\)或\(Zag\ ...

  9. 【学术篇】NOIP2017 d2t3 列队phalanx splay做法

    我可去他的吧.... ==============先胡扯些什么的分割线================== 一道NOIP题我调了一晚上...(其实是因为昨晚没有找到调试的好方法来的说...) 曾经我以 ...

随机推荐

  1. [改善Java代码]使用构造函数协助描述枚举项

    一.分析 一般来说,我们经常使用的枚举项只有一个属性,即排序号,其默认值是从0.1.2... ....但是除了排序号外,枚举还有一个(或多个)属性:枚举描述,它的含义是通过枚举的构造函数,声明每个枚举 ...

  2. 24小时学通Linux内核之进程

    都说这个主题不错,连我自己都觉得有点过大了,不过我想我还是得坚持下去,努力在有限的时间里学习到Linux内核的奥秘,也希望大家多指点,让我更有进步.今天讲的全是进程,这点在大二的时候就困惑了我,结果那 ...

  3. CSS3—三角形

    话不多说看效果:演示效果,runjs 1.加了宽高和border,边用不同颜色显示,每条边都是一个梯形 2.去掉宽高,每条边都是三角形 3.只显示其中一条边就是不同的三角形了,是不是很简单,改变bor ...

  4. Jersey(1.19.1) - Root Resource Classes

    Root resource classes are POJOs (Plain Old Java Objects) that are annotated with @Path have at least ...

  5. hive,spark的远程调试设置

    spark的远程调试 spark-env.sh文件里面,加上下面配置即可: if [ "$DEBUG_MODE" = "true" ]; then export ...

  6. WebAPI GET和POST请求的几种方式

    GET请求 1.无参数get请求 一般get请求有两种写法,一种是$.get()   一种是$.ajax({type:"get"}),我个人比较喜欢用后者. 下面例子主要是get无 ...

  7. Java之绘制五环图案

    前面已经介绍过绘制方法.这里不再赘述. package com.caiduping; import java.awt.BasicStroke; import java.awt.Color; impor ...

  8. SQL Server 错误行号

    https://msdn.microsoft.com/zh-cn/library/ms178600.aspx 返回发生错误的行号,该错误导致运行 TRY…CATCH 构造的 CATCH 块. 语法 E ...

  9. PC电脑运行Android模拟器总是弹出“视频源”窗体的原因和解决方案

    原因: PC电脑运行Android模拟器时弹出“视频源”窗体,会让你"选择视频设备",如:HP TruevIsion HD,而这个视频设备就是你电脑中的内置摄像头,这个内置摄像头在 ...

  10. plsqldev与sqldeveloper

    plsqldev连接 1.连接不同服务器,要修改tnsnames.ora文件,具体如下修改如下位置 # tnsnames.ora Network Configuration File: \app\us ...