Face questions
Resolve
Splay segment tree and two trees are nested together, almost equal to the constant INF, but eventually over luck
Thinking is relatively simple, the maintenance of the original array subscripts a segment tree, then a segment in each tree node, to maintain a weight value of the corresponding section Splay. Briefly about the operation:
0. extraction interval
This operation is the foundation of 1,2,4,5 operation, in fact, relatively easy to implement, the segment tree, run a race, if asked interval contains a range of node coverage, just keep it in an array number of the node, and then return on the line
1. queries within range of rank k
Extraction interval, to find all the Splay interval, respectively, is smaller than the number of values of k, a phase can Jia Houjia
2. Query Interval k-th largest
Extraction interval, find all Splay interval, because of how Splay trees, this operation is clearly not the same as a general Splay query, only half of the answer, transformed into a operation, and then check the ranking on the line
3. Single-point modification
To find the segment tree down all the nodes contain pos, these nodes corresponding Splay the original value by deleting, adding new value
4. precursor seek
Also find all Splay within range, respectively to find precursors, the precursor to the maximum output. But k may not Splay in, so we need to find k greater than or equal weights lowest node, it will rotate to the root, to find precursors, but may not be the precursor, is inserted in each of them Splay -inf, ranking queries remember to subtract
The subsequent seek
Similar operations precursor, k less than or equal to find the maximum value of the node weights, rotation to the root, to find a successor, and each of them remember Splay line insert inf
Most operations are of their own YY, may not be very good, but my long and boring debugging code is not long, is not easy.
The code (340 OK):
#include<bits/stdc++.h> using namespace std; const int maxn = 100005, inf = 2147483647; 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[maxn<<1], rt, a[maxn]; int tot, cnt, lson[maxn<<1], rson[maxn<<1], stak[maxn], top, s[maxn], snum; struct Splay_tree{ int fa, s[2], val, siz, num; } p [maxn* 20]; void update(int x) { int ls = tr[x].s[0], rs = tr[x].s[1]; tr[x].siz = tr[ls].siz + tr[rs].siz + tr[x].num; } 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, int id) { int y, z; while(tr[x].fa != to) { y = tr[x].fa;z = tr[y].fa; if(z != to) Rotate((tr[y].s[0] == x) ^ (tr[z].s[0] == y)? x: y); Rotate(x); } if(!to) root[id] = x; } void Insert(int x, int v) { int now = root[x], ff = 0; while(now) { ff = now; tr[now].siz ++; if(tr[now].val == v) break; now = tr[now].s[v>tr[now].val]; } if(now) tr[now].num ++; else { if(snum) now = s[snum--]; else now = ++cnt; tr[now].val = v; tr[ff].s[v>tr[ff].val] = now; tr[now].fa = ff; tr[now].num = 1; tr[now].siz = 1; tr[now].s[0] = tr[now].s[1] = 0; } Splay(now, 0, x); } void build(int &x, int l, int r) { x = ++tot; root[x] = ++cnt; tr[root[x]].val = -inf; tr[root[x]].siz = tr[root[x]].num = 1; tr[0].s[1] = root[x]; Insert(x, inf); for(int i = l; i <= r; ++i) Insert(x, a[i]); if(l == r) return ; int mid = (l + r)>>1; build(lson[x], l, mid); build(rson[x], mid + 1, r); } void Extract(int x, int l, int r, int L, int R) { if(l <= L && R <= r) { stak[++top] = x; return ; } int mid = (L + R)>>1; if(l <= mid) Extract(lson[x], l, r, L, mid); if(mid < r) Extract(rson[x], l, r, mid + 1, R); } int Queryrk(int id, int x) { int now = root[id], ret = 0; while(now) { int ls = tr[now].s[0], rs = tr[now].s[1]; if(x < tr[now].val) { if(ls) now = ls; else break; } else if(x == tr[now].val) { ret += tr[ls].siz ; break; } else { ret += tr[ls].siz + tr[now].num; if(rs) now = rs; else break; } } tr[0].s[1] = root[id]; Splay(now, 0, id); return ret; } int work1(int x) { int ret = -top; while(top) { ret += Queryrk(stak[top], x); top --; } return ret + 1; } int check(int x) { int ret = 0; for(int i = 1; i <= top; ++i) ret += Queryrk(stak[i], x); return ret + 1; } int work2(int x) { x += top; int l = 0, r = 1e8, mid, ret = 0; while(l <= r) { mid = (l + r)>>1; if(check(mid) <= x) ret = mid, l = mid + 1; else r = mid - 1; } top = 0; return ret; } int Find(int now, int x) { while(1) { int ls = tr[now].s[0], rs = tr[now].s[1]; if(tr[now].val == x) return now; if(x < tr[now].val) now = ls; else now = rs; } } int Querypre(int now) { now = tr[now].s[0]; while(tr[now].s[1]) now = tr[now].s[1]; return now; } int Querynxt(int now) { now = tr[now].s[1]; while(tr[now].s[0]) now = tr[now].s[0]; return now; } void Modify(int x, int pos, int l, int r, int v) { tr[0].s[1] = root[x]; int y = Find(root[x], a[pos]); Splay(y, 0, x); int pre = Querypre(root[x]); int nxt = Querynxt(root[x]); Splay(pre, 0, x);Splay(nxt, pre, x); if(tr[y].num > 1) { tr[y].num --; tr[y].siz --; } else { s[++snum] = y; tr[nxt].s[0] = 0; } update(nxt);update(pre); Insert(x, v); if(l == r) { a[pos] = v; return ; } int mid = (l + r)>>1; if(pos <= mid) Modify(lson[x], pos, l, mid, v); else Modify(rson[x], pos, mid + 1, r, v); } int Findmx(int now, int x) { int ret = 0; while(now) { int ls = tr[now].s[0], rs = tr[now].s[1]; if(tr[now].val == x) return now; if(tr[now].val > x) { ret = now; now = ls; } else now = rs; } return ret; } int Findmn(int now, int x) { int ret = 0; while(now) { int ls = tr[now].s[0], rs = tr[now].s[1]; if(tr[now].val == x) return now; if(tr[now].val < x) { ret = now; now = rs; } else now = ls; } return ret; } int work3(int x) { int ret = -inf; while(top) { tr[0].s[1] = root[stak[top]]; int now = Findmx(root[stak[top]], x); Splay(now, 0, stak[top]); int pre = Querypre(root[stak[top]]); ret = max(ret, tr[pre].val); top--; } return ret; } int work4(int x) { int ret = inf; while(top) { tr[0].s[1] = root[stak[top]]; int now = Findmn(root[stak[top]], x); Splay(now, 0, stak[top]); int nxt = Querynxt(root[stak[top]]); ret = min(ret, tr[nxt].val); top--; } return ret; } int main() { read(n);read(m); for(int i = 1; i <= n; ++i) read(a[i]); build(rt, 1, n); for(int i = 1; i <= m; ++i) { int opt, l, r, k, pos; read(opt); if(opt == 1) { read(l);read(r);read(k); Extract(rt, l, r, 1, n); printf("%d\n", work1(k)); } else if(opt == 2) { read(l);read(r);read(k); Extract(rt, l, r, 1, n); printf("%d\n", work2(k)); } else if(opt == 3) { read(pos);read(k); Modify(rt, pos, 1, n, k); } else if(opt == 4) { read(l);read(r);read(k); Extract(rt, l, r, 1, n); printf("%d\n", work3(k)); } else { read(l);read(r);read(k); Extract(rt, l, r, 1, n); printf("%d\n", work4(k)); } } return 0; }