[BZOJ1901]Zju2112 Dynamic Rankings
[BZOJ1901]Zju2112 Dynamic Rankings
试题描述
给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。你需要编一个这样的程序,从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令。对于每一个询问指令,你必须输出正确的回答。 第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。分别表示序列的长度和指令的个数。第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。接下来的m行描述每条指令,每行的格式是下面两种格式中的一种。 Q i j k 或者 C i t Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t。
输入
输出
对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。
输入示例
5 3 3 2 1 4 7 Q 1 4 3 C 2 6 Q 2 5 3
输出示例
3 6
数据规模及约定
见“试题描述”
题解
打了一波线段树套 treap,相比于主席树套树状数组来说慢多了。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | #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; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步