Face questions
Resolve
This question is most Splay assembly of the classic operation, wys in class the teacher talked about, this topic is still very worth doing
Exercise group:
Splay operations on all sections required extraction interval, if you want to extract a [l, r] interval, need only point to l-1 is the root, then r + 1 point to the root of the right son, then left and right son of the son of the sub-tree root whole pieces of what we want to extract the interval
Operation 1: Insert
The question is not inserted insert a number, but a number of columns inserted, one by one, will certainly be inserted T, so put the number of columns inserted before the completion of a tree, and then extract the interval, when his son left his son the right to the root of son left empty, just put the new root of the tree roots hanging in the right son, last updated information to
Action 2: Delete
Or the first extraction interval, the right side off the root of the son and the son of its left connected to the line, but the limited space of this question, you need to recover the node number, it is best to open a stack to store numbers, with the queue, then a waste of space, and must be open to a large array on CodeVS AC, it does not seem to differ in Los Valley, of course, I mean handwritten queue queue, you impress me with STL
Operation 3: Modify
The same is the first extraction interval, the root of the left and right son's son marked mark once in a while
Operation 4: Flip
Extraction interval, the root of the left and right son's son marked mark after modification
Action 5: sum
Extraction interval, output
Operation 6: sum of the maximum and subsequence
Finally do extraction interval, and direct output on the line. But when the maintenance information is very troublesome, and the largest sub-segment tree columns similar sum, we need to maintain maximum interval sequences, and the maximum range of about subsequence and, at the time of the update up, you need to operate like this which is the left son of x ls, rs is the right son, MX and is the largest sub-sequences and, lx is the largest sub-interval sequence of the left and, rx is the right range and maximum subsequence
detail:
0 nodes mx assigned to negative infinity, because some point no son left or right son, to avoid making mistakes (director wys tune the details of one hour) when updating the answer
When the next pass mark should note that there is no left or right son, son, or change the information node 0, I do half an hour
Stretching operation (splay) Do not write hung up, I did a one hour
Code:
#include<bits/stdc++.h> using namespace std; const int maxn = 500005, inf = 0x3f3f3f3f; template<class T> void read(T &re) { re=0; T sign=1; char tmp; while((tmp=getchar())&&(tmp<'0'||tmp>'9')) if(tmp=='-') sign=-1; re=tmp-'0'; while((tmp=getchar())&&(tmp>='0'&&tmp<='9')) re=(re<<3)+(re<<1)+(tmp-'0'); re*=sign; } int n, m, root, id[maxn], tot; int a[maxn]; struct splay_tree{ int s[2], siz, fa, tag; int val, mx, lx, rx, sum, c; void init(int x) { val = sum = mx = x; lx = rx = max(x, 0); siz = 1; c = inf; } void Clear() { s[0] = s[1] = siz = fa = tag = 0; val = lx = rx = sum = mx = 0; c = inf; } }tr[maxn]; int stak[maxn], top; void update(int x) { int ls = tr[x].s[0], rs = tr[x].s[1]; tr[x].sum = tr[ls].sum + tr[rs].sum + tr[x].val; tr[x].siz = tr[ls].siz + tr[rs].siz + 1; tr[x].mx = max(tr[ls].mx, tr[rs].mx); tr[x].mx = max(tr[x].mx, tr[ls].rx + tr[rs].lx + tr[x].val); tr[x].lx = max(tr[ls].lx, tr[ls].sum + tr[x].val + tr[rs].lx); tr[x].rx = max(tr[rs].rx, tr[rs].sum + tr[x].val + tr[ls].rx); } void spread(int x) { int ls = tr[x].s[0], rs = tr[x].s[1]; if(tr[x].c != inf) { if(ls) { tr[ls].val = tr[ls].c = tr[x].c; tr[ls].sum = tr[ls].siz * tr[x].c; tr[ls].lx = tr[ls].rx = max(tr[ls].sum, 0); tr[ls].mx = max(tr[ls].val, tr[ls].sum); } if(rs) { tr[rs].val = tr[rs].c = tr[x].c; tr[rs].sum = tr[rs].siz * tr[x].c; tr[rs].lx = tr[rs].rx = max(tr[rs].sum, 0); tr[rs].mx = max(tr[rs].val, tr[rs].sum); } tr[x].c = inf; tr[x].tag = 0; } if(tr[x].tag) { if(ls) { tr[ls].tag ^= 1; swap(tr[ls].lx, tr[ls].rx); swap(tr[ls].s[0], tr[ls].s[1]); } if(rs) { tr[rs].tag ^= 1; swap(tr[rs].lx, tr[rs].rx); swap(tr[rs].s[0], tr[rs].s[1]); } tr[x].tag = 0; } } void Rotate(int x) { int y = tr[x].fa, z = tr[y].fa, k = (tr[y].s[1] == x), w = (tr[z].s[1] == y), son = tr[x].s[k^1]; tr[y].s[k] = son;tr[son].fa = y; tr[x].s[k^1] = y;tr[y].fa = x; tr[z].s[w] = x;tr[x].fa = z; update(y);update(x); } void Splay(int x, int to) { while(tr[x].fa != to) { int y = tr[x].fa, z = tr[y].fa; if(z == to) { Rotate(x); break; } Rotate((tr[y].s[1] == x) != (tr[z].s[1] == y) ? x: y); Rotate(x); } if(!to) root = x; } int Find(int x) { int now = root; while(1) { spread(now); int ls = tr[now].s[0], rs = tr[now].s[1]; if(x == tr[ls].siz + 1) return now; if(x <= tr[ls].siz) now = ls; else x -= tr[ls].siz + 1, now = rs; } } void build(int l, int r, int f) { int mid = (l + r)>>1, now = id[mid], pre = id[f]; if(l == r) tr[now].init(a[mid]); if(l < mid) build(l, mid - 1, mid); if(mid < r) build(mid + 1, r, mid); tr[now].val = a[mid]; tr[now].fa = pre; tr[now].c = inf; update(now); tr[pre].s[mid >= f] = now; } void Insert(int pos, int len) { for( int i = 1; i <= len; ++i) read(a[i]); for( int i = 1; i <= len; ++i) if(top) id[i] = stak[top--]; else id[i] = ++tot; build(1, len, 0); int x = id[(1+len)>>1]; int y = Find(pos + 1), z = Find(pos + 2); Splay(y, 0);Splay(z, y); tr[x].fa = z; tr[z].s[0] = x; update(z);update(y); } void Recycle( int x) { if(!x) return ; int ls = tr[x].s[0], rs = tr[x].s[1]; stak[++top] = x; tr[x].Clear(); if(ls) Recycle(ls); if(rs) Recycle(rs); } void Del(int pos, int len) { int x = Find(pos), y = Find(pos + len + 1); Splay(x, 0);Splay(y, x); Recycle(tr[y].s[0]); tr[y].s[0] = 0; update(y);update(x); } void Change(int pos, int len, int val) { int x = Find(pos), y = Find(pos + len + 1); Splay(x, 0);Splay(y, x); int z = tr[y].s[0]; tr[z].val = tr[z].c = val; tr[z].sum = tr[z].siz * val; tr[z].lx = tr[z].rx = max(tr[z].sum, 0); tr[z].mx = max(tr[z].val, tr[z].sum); update(y);update(x); } void Rever(int pos, int len) { int x = Find(pos), y = Find(pos + len + 1); Splay(x, 0);Splay(y, x); int z = tr[y].s[0]; if(tr[z].c == inf) { tr[z].tag ^= 1; swap(tr[z].lx, tr[z].rx); swap(tr[z].s[0], tr[z].s[1]); update(y);update(x); } } int Query(int pos, int len) { int x = Find(pos), y = Find(pos + len + 1); Splay(x, 0);Splay(y, x); int z = tr[y].s[0]; return tr[z].sum; } int main() { read(n);read(m); tr[0].mx = a[1] = a[n+2] = -inf; for( int i = 1; i <= n; ++i) read(a[i+1]); for( int i = 1; i <= n + 2; ++i) id[i] = i; build(1, n + 2, 0); root = (n + 3)>>1; tot = n + 2; for( int i = 1; i <= m; ++i) { char opt[10]; int pos, len; scanf("%s", opt); if(opt[0] == 'I') { read(pos);read(len); Insert(pos, len); } else if(opt[0] == 'D') { read(pos);read(len); Del(pos, len); } else if(opt[0] == 'M' && opt[2] == 'K') { int val; read(pos);read(len);read(val); Change(pos, len, val); } else if(opt[0] == 'R') { read(pos);read(len); Rever(pos, len); } else if(opt[0] == 'G') { read(pos);read(len); printf("%d\n", Query(pos, len)); } else printf("%d\n", tr[root].mx); } return 0; }