给定两种操作,一种是把一个数列的某一段切下来插到剩余数列的某一个位置上。 一种是翻转操作,把数列的某一段进行翻转。

都是Splay的基本操作。标准的Rotateto调整出 [a,b]区间。然后对[a,b]区间修改parent标记和child标记。然后记住PushUp把修改标记推到树根上。简单一点就直接对某个节点spaly(x,0)就OK!

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

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

HDU 3487 Splay的更多相关文章

  1. HDU 3487 Splay tree

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  2. HDU 3487 Play with Chain(Splay)

    题目大意 给一个数列,初始时为 1, 2, 3, ..., n,现在有两种共 m 个操作 操作1. CUT a b c 表示把数列中第 a 个到第 b 个从原数列中删除得到一个新数列,并将它添加到新数 ...

  3. hdu 3487 Play with Chain

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 YaoYao is fond of playing his chains. He has a c ...

  4. hdu 3436 splay树+离散化*

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  5. hdu 4453 splay

    Looploop Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  6. HDU 3487:Play with Chain(Splay)

    http://acm.hdu.edu.cn/showproblem.php?pid=3487 题意:有两种操作:1.Flip l r ,把 l 到 r 这段区间 reverse.2.Cut a b c ...

  7. HDU 3487 Play with Chain | Splay

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  8. HDU 3487 Play with Chain 【Splay】

    1-n的序列,有两种操作: 1,将一段区间翻转 2,将一段区间切下来放到剩余序列的第C个数后 采用延迟更新的方法维护区间的翻转,并维护一个size域. 添加一个最大点和一个最小点,防止出界 翻转时,将 ...

  9. HDU 3487 Play with Chain (splay tree)

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

随机推荐

  1. ionic获取事件中的对象

    ng-click="submit1($event, 'argsTest’)" $scope.submit1=function(event, args){ var target = ...

  2. HDU 1978 How many ways (DP)

    How many ways Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  3. 集群服务器Session同步

    事实上,网站总是有状态的.每一个登录信息.用户信息常常被存储在session内部.而当一个网站被部署在不止一台服务器的时候,就会遇到session同步的问题.事实上即使一个很小的网站,也要至少有两台服 ...

  4. poj 1523 求割点

    思路:对于所有节点,每次找的子树,key[root]++;输出时,对于根节点就输出key[root],对于其它节点i,输出key[i]+1; #include<iostream> #inc ...

  5. Python内存解析浅学

    1.内存管理 首先理解变量,和内存特性 1.       Python中无须声明变量, 2.       无须指定类型 3.       不用关心内存管理 4.       变量名会被回收 5.    ...

  6. TCP基础知识

    TCP/IP网络协议栈分为应用层(Application).传输层(Transport).网络层(Network)和链路层(Link)四层.如下图所示 两台计算机通过TCP/IP协议通讯的过程如下所示 ...

  7. Emmet 语法大全(缩写语法/sublime 插件)

    Emmet 使用类似于 CSS 选择器的语法描述元素在生成的文档树中的位置及其属性. 元素 可以使用元素名(如 div 或者 p)来生成 HTML 标签.Emmet 没有预定义的有效元素名的集合,可以 ...

  8. Delphi IP 控件源码

    interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,ComCtrls, Co ...

  9. Httpclient 和jsoup结和提取网页内容(某客学院视频链接)

    最近在极客学院获得体验会员3个月,然后就去上面看了看,感觉课程讲的还不错.整好最近学习Android,然后去上面找点视频看看.发现只有使用RMB买的会员才能在上面下载视频.抱着试一试的态度,去看他的网 ...

  10. 我的手机华为荣耀7,运行android程序不输出Log

    解决方法:1 进入手机拨号界面2 输入*#*#2846579#*#*3 输入完毕后自动跳转到<工程菜单>界面4 依次选择后台设置-->LOG设置-->在此可以看见一些列关于LO ...