• hdu4453 Looploop 2012年杭州现场赛 Splay


    题意:维护一个圈,实现六个功能,给某位置起的一些数增加某值,反转某一段数,添加删除某些数,移动当前所指的位置,

    简单的splay,把圈拆成链,对于每种操作,处理一下。

    #define inf 0x3f3f3f3f
    #define keyTree (ch[ ch[root][1] ][0])
    
    const int maxn = 222222;
    
    struct SplayTree {
      int sz[maxn];
      int ch[maxn][2];
      int pre[maxn];
      int root , top1 , top2;
      int ss[maxn] , que[maxn];
    
      void Rotate(int x,int f) {
        int y = pre[x];
        push_down(y);
        push_down(x);
        ch[y][!f] = ch[x][f];
        pre[ ch[x][f] ] = y;
        pre[x] = pre[y];
        if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] = x;
        ch[x][f] = y;
        pre[y] = x;
        push_up(y);
      }
      void Splay(int x,int goal) {
        push_down(x);
        //puts("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
        while(pre[x] != goal) {
          int y = pre[x], z = pre[y];
          push_down(z);
          push_down(y);
          push_down(x);
          if(pre[pre[x]] == goal) {
            Rotate(x , ch[pre[x]][0] == x);
          } else {
            int y = pre[x] , z = pre[y];
            int f = (ch[z][0] == y);
            if(ch[y][f] == x) {
              Rotate(x , !f) , Rotate(x , f);
            } else {
              Rotate(y , f) , Rotate(x , f);
            }
          }
        }
        push_up(x);
        if(goal == 0) root = x;
      }
      void RotateTo(int k,int goal) {//把第k位的数转到goal下边
        int x = root;
        push_down(x);
        while(sz[ ch[x][0] ] != k) {
          // printf("x = %d k = %d sz[x] = %d
    ",x,k,sz[x]);
          if(k < sz[ ch[x][0] ]) {
            x = ch[x][0];
          } else {
            k -= (sz[ ch[x][0] ] + 1);
            x = ch[x][1];
          }
          push_down(x);
        }
        Splay(x,goal);
      }
    
      //以上一般不修改//////////////////////////////////////////////////////////////////////////////
      void debug() {
        printf("%d
    ",root);
        Treaval(root);
      }
      void Treaval(int x) {
        push_down(x);
        if(x) {
          Treaval(ch[x][0]);
          printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d
    ",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x]);
          Treaval(ch[x][1]);
        }
      }
      //以上Debug
      //以下是题目的特定函数:
      void NewNode(int &x,int c) {
        x = ++top1;
        ch[x][0] = ch[x][1] = pre[x] = 0;
        sz[x] = 1;
        val[x] = c;
        lazy[x] = add[x] = 0 ;
      }
      //把延迟标记推到孩子
      void push_down(int x) {
        if(lazy[x] != 0 )
        {
          rev(ch[x][0]);
          rev(ch[x][1]);
          //swap(add[ch[x][0]],add[ch[x][1]]);
          lazy[x] = 0 ;
        }
        if(add[x] != 0 )
        {
          val[ch[x][0]] += add[x];
          val[ch[x][1]] += add[x];
          add[ch[x][0]] += add[x];
          add[ch[x][1]] += add[x];
          add[x] = 0 ;
        }
        return ;
      }
      //把孩子状态更新上来
      void push_up(int x) {
        sz[x] = 1 + sz[ ch[x][0] ] + sz[ ch[x][1] ];
      }
      /*初始化*/
      void makeTree(int &x,int l,int r,int f) {
        if(l > r) return ;
        int m = (l + r)>>1;
        NewNode(x , num[m]);        /*num[m]权值改成题目所需的*/
        makeTree(ch[x][0] , l , m - 1 , x);
        makeTree(ch[x][1] , m + 1 , r , x);
        pre[x] = f;
        push_up(x);
      }
      void clear() {
        cnt = 0 ;
        ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0;
        add[0] = lazy[0] = 0 ;
        root = top1 = 0;
        //为了方便处理边界,加两个边界顶点
        NewNode(root , -inf);
        NewNode(ch[root][1] , inf);
        pre[top1] = root;
        sz[root] = 2;
      }
      void init(int pos,int n) {
        clear();
        cnt =  n;
        RotateTo(pos , 0 );
        RotateTo(pos + 1, root);
        makeTree(keyTree , 1 , n   , ch[root][1]);
        push_up(ch[root][1]);
        push_up(root);
      }
      void update(int u,int v,int _add )
      {
        RotateTo(u - 1 , 0 );
        RotateTo(v + 1, root );
        add[keyTree] += _add;
        val[keyTree] += _add;
        push_up(root);
        //Splay(keyTree,root);
      }
      void rev(int x)
      {
        if(x == 0 ) return;
        swap(ch[x][0] ,ch[x][1]);
        lazy[x] ^= 1;
      }
      void lz(int u,int v )
      {
        RotateTo(u - 1 , 0 );
        RotateTo(v + 1 , root );
        rev(keyTree);
        //Splay(keyTree,root);
      }
      int split(int u,int v )
      {
        RotateTo(u - 1 , 0 );
        RotateTo(v + 1 , root );
        int res = keyTree;
        keyTree = 0 ;
        push_up(ch[root][1]);
        push_up(root);
        return res ;
      }
      void hb(int k,int ts)
      {
        RotateTo(k - 1 ,0 );
        RotateTo(k , root);
        keyTree = ts ;
        pre[ts] = ch[root][1];
        push_up(ch[root][1]);
        push_up(root);
      }
      void insert(int k,int val)
      {
        cnt ++ ;
        RotateTo(k - 1 , 0 );
        RotateTo(k , root ) ;
        NewNode(keyTree,val);
        pre[keyTree] = ch[root][1];
        push_up(ch[root][1]);
        push_up(root);
      }
      int getkth(int k )
      {
        int x = root ;
        push_down(x);
        while(sz[ ch[x][0] ] != k) {
          // printf("x = %d k = %d sz[x] = %d
    ",x,k,sz[x]);
          if(k < sz[ ch[x][0] ]) {
            x = ch[x][0];
          } else {
            k -= (sz[ ch[x][0] ] + 1);
            x = ch[x][1];
          }
          push_down(x);
        }
        return val[x];
      }
      void del(int k) {
        RotateTo(k - 1 , 0);
        RotateTo(k + 1 , root);
        //printf("val = %d
    ",val[keyTree]);
        //printf("sz = %d
    ",sz[keyTree]);
        cnt -- ;
        keyTree = 0 ;
        push_up(ch[root][1]);
        push_up(root);
        // erase(keyTree);
      }
      int cnt ;
      /*这是题目特定变量*/
      int num[maxn];
      int val[maxn];
      int add[maxn];
      int lazy[maxn];
    
    } spt;
    
    int n,m,k1,k2;
    int wh;
    int main()
    {
      int cas;
      cas = 0 ;
      char str[10];
      while(
            scanf("%d%d%d%d",&n,&m,&k1,&k2)!=EOF && !(n == 0 && m == 0 && k1 == 0 && k2 == 0 ) )
      {
        for(int i =1 ; i<= n ; i ++ ) scanf("%d",&spt.num[i]);
        spt.init(0,n);
        wh =  1 ;
        printf("Case #%d:
    ",++cas);
        int x;
        while(m -- )
        {
          scanf("%s",str);
          if( str[0] == 'q' )
          {
            int ans = spt.getkth(wh);
            printf("%d
    ",ans);
          }
          else if( str[0] == 'r' )
          {
            if(wh + k1 - 1 <= spt.cnt)
            {
              spt.lz(wh , wh + k1 - 1);
            }
            else
            {
              int p1,p2,p3,p4;
              p4 = spt.cnt;
              p1 = wh + k1 - 1 - spt.cnt;
              p2 = spt.split(1,p1);
              wh = wh - p1;
              p4 = p4 - p1;
              spt.hb(p4 + 1 ,p2);
              p1 = wh + k1 - 1 ;
              spt.lz(wh,p1);
            }
          }
          else if(str[0] == 'i')
          {
            scanf("%d",&x);
            spt.insert(wh + 1 ,x);
          }
          else if(str[0] == 'm')
          {
            scanf("%d",&x);
            if(x == 1 )
            {
              wh -- ;
              if(wh == 0 ) wh = spt.cnt;
            }
            else
            {
              wh ++ ;
              if(wh >spt.cnt) wh = 1;
            }
          }
          else if(str[0] == 'd')
          {
            if(wh == spt.cnt)
            {
              spt.del(wh);
              wh = 1;
            }
            else
            {
              spt.del(wh);
            }
          }
          else if(str[0] == 'a')
          {
            scanf("%d",&x);
            int p1,p2,p3,lef;
            if(wh + k2 - 1 <= spt.cnt)
            {
              spt.update(wh,wh + k2 - 1 ,x);
            }
            else
            {
              lef  = wh + k2 - 1 - spt.cnt;
             // printf("%d %d 
    ",k2,lef);
              spt.update(1,lef,x);
              spt.update(wh,spt.cnt,x);
            }
          }
         // spt.debug();
        }
      }
      return 0;
    }
    View Code

    7k+的代码,居然调出来了,好开心。

  • 相关阅读:
    面向对象设计原则
    简单工厂模式和策略模式结合使用php
    lua string
    js.ajax优缺点,工作流程
    深入理解JavaScript是如何实现继承的
    js中哈希表的几种用法总结
    js,indexOf()、lastIndexOf()
    js获取字符串字节数方法小结
    JS(JavaScript)插入节点的方法appendChild与insertBefore
    js中的this关键字详解
  • 原文地址:https://www.cnblogs.com/jh818012/p/3278611.html
Copyright © 2020-2023  润新知