zoukankan      html  css  js  c++  java
  • HDU 3487 Splay

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

    都是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
    ",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
    ",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:   
  • 相关阅读:
    seajs加载angularjs
    seajs加载jquery提示$ is not a function
    java 动态代理
    C#第三章--对象和类
    Android笔记--两种双击退出程序的方法
    Android--Volley基本用法及自定义
    Win10专业版只要12.99元?应用商店Bug福利也算数
    新人报道
    排序

  • 原文地址:https://www.cnblogs.com/sosi/p/3696439.html
Copyright © 2011-2022 走看看