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\n", 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); } }