【ZOJ】2112 Dynamic Rankings
树状数组套主席树模板题目。
1 /* 2112 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 //#define lson l, mid, rt<<1 41 //#define rson mid+1, r, rt<<1|1 42 43 typedef struct { 44 int l, r, k; 45 int op; 46 } ques_t; 47 48 const int maxq = 10005; 49 const int maxn = 60005; 50 const int maxm = 2500010; 51 int n, q, m, tot; 52 int a[maxn], b[maxn]; 53 int S[maxn], T[maxn]; 54 int lson[maxm], rson[maxm], C[maxm]; 55 ques_t Q[maxq]; 56 57 void init() { 58 tot = m = 0; 59 } 60 61 void Build(int l, int r, int& rt) { 62 rt = tot++; 63 C[rt] = 0; 64 if (l == r) 65 return ; 66 67 int mid = (l + r) >> 1; 68 69 Build(l, mid, lson[rt]); 70 Build(mid+1, r, rson[rt]); 71 } 72 73 int Insert(int rt, int p, int val) { 74 int nrt = tot++, ret = nrt; 75 int l = 0, r = m - 1, mid; 76 77 C[nrt] = C[rt] + val; 78 while (l < r) { 79 mid = (l + r) >> 1; 80 if (p <= mid) { 81 lson[nrt] = tot++; 82 rson[nrt] = rson[rt]; 83 nrt = lson[nrt]; 84 rt = lson[rt]; 85 r = mid; 86 } else { 87 lson[nrt] = lson[rt]; 88 rson[nrt] = tot++; 89 nrt = rson[nrt]; 90 rt = rson[rt]; 91 l = mid + 1; 92 } 93 C[nrt] = C[rt] + val; 94 } 95 96 return ret; 97 } 98 99 int lowest(int x) { 100 return -x & x; 101 } 102 103 int use[maxn]; 104 105 void add(int x, int p, int delta) { 106 while (x <= n) { 107 S[x] = Insert(S[x], p, delta); 108 x += lowest(x); 109 } 110 } 111 112 int sum(int x) { 113 int ret = 0; 114 115 while (x) { 116 ret += C[lson[use[x]]]; 117 x -= lowest(x); 118 } 119 120 return ret; 121 } 122 123 int Query(int L, int R, int k) { 124 int lrt = T[L-1]; 125 int rrt = T[R]; 126 int l = 0, r = m - 1, mid; 127 int tmp; 128 129 for (int i=L-1; i; i-=lowest(i)) 130 use[i] = S[i]; 131 for (int i=R; i; i-=lowest(i)) 132 use[i] = S[i]; 133 134 while (l < r) { 135 mid = (l + r) >> 1; 136 tmp = sum(R) - sum(L-1) + C[lson[rrt]] - C[lson[lrt]]; 137 if (tmp >= k) { 138 for (int i=L-1; i; i-=lowest(i)) 139 use[i] = lson[use[i]]; 140 for (int i=R; i; i-=lowest(i)) 141 use[i] = lson[use[i]]; 142 r = mid; 143 lrt = lson[lrt]; 144 rrt = lson[rrt]; 145 } else { 146 for (int i=L-1; i; i-=lowest(i)) 147 use[i] = rson[use[i]]; 148 for (int i=R; i; i-=lowest(i)) 149 use[i] = rson[use[i]]; 150 k -= tmp; 151 l = mid + 1; 152 lrt = rson[lrt]; 153 rrt = rson[rrt]; 154 } 155 } 156 157 return l; 158 } 159 160 void solve() { 161 sort(b, b+m); 162 m = unique(b, b+m) - b; 163 Build(0, m-1, T[0]); 164 rep(i, 1, n+1) { 165 int id = lower_bound(b, b+m, a[i]) - b; 166 T[i] = Insert(T[i-1], id, 1); 167 } 168 rep(i, 1, n+1) 169 S[i] = T[0]; 170 171 int ans, lid, rid; 172 173 rep(i, 0, q) { 174 if (Q[i].op) { 175 lid = lower_bound(b, b+m, a[Q[i].l]) - b; 176 rid = lower_bound(b, b+m, Q[i].k) - b; 177 add(Q[i].l, lid, -1); 178 add(Q[i].l, rid, 1); 179 a[Q[i].l] = Q[i].k; 180 } else { 181 int id = Query(Q[i].l, Q[i].r, Q[i].k); 182 ans = b[id]; 183 printf("%d\n", ans); 184 } 185 } 186 } 187 188 int main() { 189 ios::sync_with_stdio(false); 190 #ifndef ONLINE_JUDGE 191 freopen("data.in", "r", stdin); 192 freopen("data.out", "w", stdout); 193 #endif 194 195 int t; 196 char op[4]; 197 198 scanf("%d", &t); 199 while (t--) { 200 scanf("%d %d", &n, &q); 201 init(); 202 rep(i, 1, n+1) { 203 scanf("%d", &a[i]); 204 b[m++] = a[i]; 205 } 206 rep(i, 0, q) { 207 scanf("%s", op); 208 if (op[0] == 'Q') { 209 Q[i].op = 0; 210 scanf("%d %d %d", &Q[i].l, &Q[i].r, &Q[i].k); 211 } else { 212 Q[i].op = 1; 213 scanf("%d %d", &Q[i].l, &Q[i].k); 214 b[m++] = Q[i].k; 215 } 216 } 217 218 solve(); 219 } 220 221 #ifndef ONLINE_JUDGE 222 printf("time = %d.\n", (int)clock()); 223 #endif 224 225 return 0; 226 }
数据发生器。
1 from copy import deepcopy 2 from random import randint, shuffle 3 import shutil 4 import string 5 6 7 def GenDataIn(): 8 with open("data.in", "w") as fout: 9 t = 20 10 bound = 10**4 11 fout.write("%d\n" % (t)) 12 for tt in xrange(t): 13 n = randint(100, 200) 14 q = randint(100, 200) 15 fout.write("%d %d\n" % (n, q)) 16 L = [] 17 for i in xrange(n): 18 x = randint(1, bound) 19 L.append(x) 20 fout.write(" ".join(map(str, L)) + "\n") 21 for i in xrange(q): 22 op = randint(0, 1) 23 if op: 24 l = randint(1, n) 25 r = randint(l, n) 26 k = randint(1, r-l+1) 27 fout.write("Q %d %d %d\n" % (l, r, k)) 28 else: 29 l = randint(1, n) 30 k = randint(1, bound) 31 fout.write("C %d %d\n" % (l, k)) 32 33 34 def MovDataIn(): 35 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 36 shutil.copyfile("data.in", desFileName) 37 38 39 if __name__ == "__main__": 40 GenDataIn() 41 MovDataIn()