原題鏈接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 #define lc root<<1 6 #define rc root<<1|1 7 #define INF 0x3f3f3f3f 8 const int Max_N = 50010; 9 struct SBT{ 10 int key, size, cnt; 11 SBT *ch[2]; 12 inline void push_up(){ 13 size = ch[0]->size + ch[1]->size + cnt; 14 } 15 int cmp(int v) const{ 16 if (v == key) return -1; 17 return v > key; 18 } 19 }*null, stack[Max_N * 18], *ptr[Max_N << 2]; 20 int sz = 0, sum = 0, arr[Max_N]; 21 void init(){ 22 null = &stack[sz++]; 23 null->key = null->size = null->cnt = 0; 24 } 25 void rotate(SBT* &x, int d){ 26 SBT *k = x->ch[!d]; 27 x->ch[!d] = k->ch[d]; 28 k->ch[d] = x; 29 k->size = x->size; 30 x->push_up(); 31 x = k; 32 } 33 void Maintain(SBT* &x, int d){ 34 if (x->ch[d] == null) return; 35 if (x->ch[d]->ch[d]->size > x->ch[!d]->size){ 36 rotate(x, !d); 37 } else if (x->ch[d]->ch[!d]->size > x->ch[!d]->size){ 38 rotate(x->ch[d], d), rotate(x, !d); 39 } else { 40 return; 41 } 42 Maintain(x, 0), Maintain(x, 1); 43 } 44 void insert(SBT* &x, int key){ 45 if (x == null){ 46 x = &stack[sz++]; 47 x->ch[0] = x->ch[1] = null; 48 x->key = key, x->size = x->cnt = 1; 49 } else { 50 int d = x->cmp(key); 51 x->size++; 52 if (-1 == d){ 53 x->cnt++; 54 return; 55 } 56 insert(x->ch[d], key); 57 x->push_up(); 58 Maintain(x, d); 59 } 60 } 61 void del(SBT* &x, int key){ 62 if (x == null) return; 63 int d = x->cmp(key); 64 x->size--; 65 if (-1 == d){ 66 if (x->cnt > 1){ 67 x->cnt--; 68 } else if (x->ch[0] == null || x->ch[1] == null){ 69 x = x->ch[0] != null ? x->ch[0] : x->ch[1]; 70 } else { 71 SBT *ret = x->ch[1]; 72 for (; ret->ch[0] != null; ret = ret->ch[0]); 73 del(x->ch[1], x->key = ret->key); 74 } 75 } else { 76 del(x->ch[d], key); 77 } 78 if (x != null) x->push_up(); 79 } 80 int sbt_rank(SBT *x, int key){ 81 int t, cur; 82 for (t = cur = 0; x != null;){ 83 t = x->ch[0]->size; 84 if (key < x->key) x = x->ch[0]; 85 else if (key >= x->key) cur += x->cnt + t, x = x->ch[1]; 86 } 87 return cur; 88 } 89 void seg_built(int root, int l, int r){ 90 for (int i = l; i <= r; i++) insert(ptr[root], arr[i]); 91 if (l == r) return; 92 int mid = (l + r) >> 1; 93 seg_built(lc, l, mid); 94 seg_built(rc, mid + 1, r); 95 } 96 void seg_query(int root, int l, int r, int x, int y, int val){ 97 if (x > r || y < l) return; 98 if (x <= l && y >= r){ 99 sum += sbt_rank(ptr[root], val); 100 return; 101 } 102 int mid = (l + r) >> 1; 103 seg_query(lc, l, mid, x, y, val); 104 seg_query(rc, mid + 1, r, x, y, val); 105 } 106 void seg_del(int root, int l, int r, int pos, int val){ 107 if (pos > r || pos < l) return; 108 del(ptr[root], val); 109 if (l == r) return; 110 int mid = (l + r) >> 1; 111 seg_del(lc, l, mid, pos, val); 112 seg_del(rc, mid + 1, r, pos, val); 113 } 114 void seg_insert(int root, int l, int r, int pos, int val) { 115 if (pos > r || pos < l) return; 116 insert(ptr[root], val); 117 if (l == r) return; 118 int mid = (l + r) >> 1; 119 seg_insert(lc, l, mid, pos, val); 120 seg_insert(rc, mid + 1, r, pos, val); 121 } 122 void gogo(int n, int a, int b, int k){ 123 int l = 0, r = INF; 124 while (l < r){ 125 sum = 0; 126 int mid = (l + r) >> 1; 127 seg_query(1, 1, n, a, b, mid); 128 if (sum < k) l = mid + 1; 129 else r = mid; 130 } 131 printf("%d\n", l); 132 } 133 int main(){ 134 #ifdef LOCAL 135 freopen("in.txt", "r", stdin); 136 freopen("out.txt", "w+", stdout); 137 #endif 138 char ch; 139 int t, n, m, a, b, k; 140 scanf("%d", &t); 141 while (t--){ 142 sz = 0, init(); 143 scanf("%d %d", &n, &m); 144 for (int i = 1; i <= n; i++) scanf("%d", &arr[i]); 145 std::fill(ptr, ptr + (n << 2), null); 146 seg_built(1, 1, n); 147 while (m--){ 148 getchar(); 149 scanf("%c", &ch); 150 if (ch == 'Q'){ 151 scanf("%d %d %d", &a, &b, &k); 152 gogo(n, a, b, k); 153 } 154 else { 155 scanf("%d %d", &a, &b); 156 seg_del(1, 1, n, a, arr[a]); 157 seg_insert(1, 1, n, a, arr[a] = b); 158 } 159 } 160 } 161 return 0; 162 } View Code