• poj3580


    第一道伸展树题。。。

     无序序列,区间翻转,区间查询最小值,区间循环移位,在给定位置插入值,删除给定位置的值;

    区间翻转:

    这个跟白书代码一致。。

    void flip(int a, int b) {
      Node *left, *mid, *right, *o;
      split(ss.root, a, left, o);
      split(o, b-a+1, mid, right);
      mid->flip ^= 1;
      ss.root = merge(merge(left, mid), right);
    }

    区间查询最小值:

    维护了mi信息。。

    void query_min(int a, int b) {
      Node *left, *mid, *right, *o;
      split(ss.root, a, left, o);
      split(o, b-a+1, mid, right);
      printf ( "%d
    ", mid->mi );
      ss.root = merge(merge(left, mid), right);
    }

     区间循环移位:

    需要特别判断给定区间的左右值。

    void revolve(int a, int b, int t) {
      if(a>b) swap(a, b);
      int len = b - a + 1;
      int idx = t%len;
      if(idx) {
        Node *left, *mid, *right, *o;
        split(ss.root, a, left, o);
        split(o, b-a+1, mid, right);
        Node *l, *r;
        split(mid, len-idx, l, r);
        mid = merge(r, l);
        ss.root = merge(merge(left, mid), right);
      }
    }

    在给定位置插入值:

    因为虚拟结点的存在,所以提根要提a+1。。。然后再插入新结点--

    void insert_at_pos(int a, int c) {
      Node *left, *right, *o;
      split(ss.root, a+1, left, right);
      Node *mid = new Node();
      mid->ch[0] = mid->ch[1] = null;
      mid->s = 1;
      mid->v = mid->mi = c;
      mid->flip = mid->lazy = 0;
      ss.root = merge(merge(left, mid), right);
    }

    删除给定位置的结点:

    void del(int a) {
      Node *left, *mid, *right, *o;
      split(ss.root, a, left, o);
      split(o, 1, mid, right);
      ss.root = merge(left, right);
    }

     另外一个数组的版本 - -:

      void add(int l, int r, int c) {
        if ( l > r ) swap(l, r);
        RotateTo(l-1, 0);
        RotateTo(r+1, root);
        int key = ch[ch[root][1]][0];
        val[key] += c;
        mi[key] += c;
        lazy2[key] += c;                                                                                                                                                                                         
        push_up(ch[root][1]);
        push_up(root);
      }
      void flip(int l, int r) {
        if ( l > r ) swap(l ,r);
        RotateTo(l-1, 0);
        RotateTo(r+1, root);
        int key = ch[ch[root][1]][0];
        lazy1[key] ^= 1;
        push_up(ch[root][1]);
        push_up(root);
      }
      void insert_at_pos(int pos, int c) {
        RotateTo(pos, 0);
        RotateTo(pos+1, root);
        int key;
        NewNode(key, c);
        ch[ch[root][1]][0] = key;
        pre[key] = ch[root][1];
        push_up(ch[root][1]);
        push_up(root);
      }
      void del(int pos) {
        RotateTo(pos-1, 0);
        RotateTo(pos+1, root);
        ch[ch[root][1]][0] = 0;
        push_up(ch[root][1]);
        push_up(root);
      }
      int quary_min(int l, int r) {
        RotateTo(l-1, 0);
        RotateTo(r+1, root);
        int key = ch[ch[root][1]][0];
        return mi[key];
      }
      void revolve(int l, int r, int t) {
        if ( l > r ) swap(l, r);
        int len = r-l+1;
        int idx = t%len;
        if ( idx ) {
          RotateTo(r-idx, 0);
          RotateTo(r+1, root);
          int key = ch[ch[root][1]][0];
          ch[ch[root][1]][0] = 0;
          push_up(ch[root][1]);
          push_up(root);
    
          RotateTo(l-1, 0);
          RotateTo(l, root);
          ch[ch[root][1]][0] = key;
          pre[key] = ch[root][1];
          push_up(ch[root][1]);
          push_up(root);
        }
      }

     

  • 相关阅读:
    【Dos-BatchPrograming】04
    【Dos-BatchPrograming】03
    【Dos-BatchPrograming】02
    【Dos-BatchPrograming】01
    【perl】01
    【Linux】Re04
    【Linux】Re03
    【Linux】Re02
    【Linux】Re01
    【C++】01
  • 原文地址:https://www.cnblogs.com/Accoral/p/3145034.html
Copyright © 2020-2023  润新知