标签:bzoj style 序列 pac 树状数组 swap 接下来 规模 ble
[BZOJ1901]Zju2112 Dynamic Rankings
试题描述
输入
输出
输入示例
5 3 3 2 1 4 7 Q 1 4 3 C 2 6 Q 2 5 3
输出示例
3 6
数据规模及约定
见“试题描述”
题解
打了一波线段树套 treap,相比于主席树套树状数组来说慢多了。。。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <algorithm> using namespace std; int read() { int x = 0, f = 1; char c = getchar(); while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); } while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); } return x * f; } #define maxn 10005 #define maxnode 1280010 struct Node { int v, r, siz; Node() {} Node(int _, int __): v(_), r(__) {} } ns[maxnode]; int ToT, rt[maxn<<2], fa[maxnode], ch[2][maxnode]; void maintain(int o) { ns[o].siz = 1; for(int i = 0; i < 2; i++) if(ch[i][o]) ns[o].siz += ns[ch[i][o]].siz; return ; } void rotate(int u) { int y = fa[u], z = fa[y], l = 0, r = 1; if(z) ch[ch[1][z]==y][z] = u; if(ch[1][y] == u) swap(l, r); fa[u] = z; fa[y] = u; fa[ch[r][u]] = y; ch[l][y] = ch[r][u]; ch[r][u] = y; maintain(y); maintain(u); return ; } void insert(int& o, int v) { if(!o) { ns[o = ++ToT] = Node(v, rand()); return maintain(o); } bool d = v > ns[o].v; insert(ch[d][o], v); fa[ch[d][o]] = o; if(ns[ch[d][o]].r > ns[o].r) { int t = ch[d][o]; rotate(t); o = t; } return maintain(o); } void del(int& o, int v) { if(!o) return ; if(ns[o].v == v) { if(!ch[0][o] && !ch[1][o]) o = 0; else if(!ch[0][o]) { int t = ch[1][o]; fa[t] = fa[o]; o = t; } else if(!ch[1][o]) { int t = ch[0][o]; fa[t] = fa[o]; o = t; } else { bool d = ns[ch[1][o]].r > ns[ch[0][o]].r; int t = ch[d][o]; rotate(t); o = t; del(ch[d^1][o], v); } } else { bool d = v > ns[o].v; del(ch[d][o], v); } return maintain(o); } int Find(int o, int v) { if(!o) return 0; int ls = ch[0][o] ? ns[ch[0][o]].siz : 0; if(v >= ns[o].v) return ls + 1 + Find(ch[1][o], v); return Find(ch[0][o], v); } int n, val[maxn]; void build(int L, int R, int o, int p) { insert(rt[o], val[p]); if(L == R) return ; int M = L + R >> 1, lc = o << 1, rc = lc | 1; if(p <= M) build(L, M, lc, p); else build(M+1, R, rc, p); return ; } void update(int L, int R, int o, int p, int v) { del(rt[o], val[p]); insert(rt[o], v); if(L == R) return ; int M = L + R >> 1, lc = o << 1, rc = lc | 1; if(p <= M) update(L, M, lc, p, v); else update(M+1, R, rc, p, v); return ; } int ql, qr; int query(int L, int R, int o, int v) { if(ql <= L && R <= qr) return Find(rt[o], v); int M = L + R >> 1, lc = o << 1, rc = lc | 1, ans = 0; if(ql <= M) ans += query(L, M, lc, v); if(qr > M) ans += query(M+1, R, rc, v); return ans; } int main() { n = read(); int q = read(); for(int i = 1; i <= n; i++) val[i] = read(), build(1, n, 1, i); while(q--) { char tp[2]; scanf("%s", tp); if(tp[0] == ‘Q‘) { ql = read(); qr = read(); int k = read(); int l = 0, r = (int)1e9; bool has = 0; while(l < r) { int mid = l + r >> 1; if(query(1, n, 1, mid) < k) { l = mid + 1; if(query(1, n, 1, l) >= k){ has = 1; printf("%d\n", l); break; } } else r = mid; } if(!has) printf("%d\n", l); } else { int p = read(), v = read(); update(1, n, 1, p, v); val[p] = v; } } return 0; }
[BZOJ1901]Zju2112 Dynamic Rankings
标签:bzoj style 序列 pac 树状数组 swap 接下来 规模 ble
原文地址:http://www.cnblogs.com/xiao-ju-ruo-xjr/p/6155889.html