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

 

原文地址:https://www.cnblogs.com/Accoral/p/3145034.html