【HDOJ】3727 Jewel
静态区间第K大值。主席树和划分树都可解。
1 /* 3727 */ 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 q; 45 int l, r, k; 46 } Ques_t; 47 48 const int maxq = 210000; 49 const int maxn = 1e5+5; 50 const int maxm = maxn * 20; 51 int a[maxn], m; 52 Ques_t Q[maxq]; 53 int T[maxn]; 54 int lson[maxm], rson[maxm], c[maxm]; 55 int tot, cur, q; 56 57 void init() { 58 tot = cur = m = 0; 59 } 60 61 int Build(int l, int r) { 62 int rt = tot++; 63 64 c[rt] = 0; 65 if (l == r) 66 return rt; 67 68 int mid = (l + r) >> 1; 69 70 lson[rt] = Build(l, mid); 71 rson[rt] = Build(mid+1, r); 72 73 return rt; 74 } 75 76 int Insert(int rt, int x, int delta) { 77 int nrt = tot++, ret = nrt; 78 int l = 0, r = m - 1, mid; 79 80 c[nrt] = c[rt] + delta; 81 while (l < r) { 82 mid = (l + r) >> 1; 83 if (x <= mid) { 84 lson[nrt] = tot++; 85 rson[nrt] = rson[rt]; 86 nrt = lson[nrt]; 87 rt = lson[rt]; 88 r = mid; 89 } else { 90 lson[nrt] = lson[rt]; 91 rson[nrt] = tot++; 92 nrt = rson[nrt]; 93 rt = rson[rt]; 94 l = mid + 1; 95 } 96 c[nrt] = c[rt] + delta; 97 } 98 99 return ret; 100 } 101 102 int Query_kth(int lrt, int rrt, int k) { 103 int l = 0, r = m - 1, mid; 104 int tmp; 105 106 while (l < r) { 107 mid = (l + r) >> 1; 108 tmp = c[lson[rrt]] - c[lson[lrt]]; 109 if (tmp >= k) { 110 lrt = lson[lrt]; 111 rrt = lson[rrt]; 112 r = mid; 113 } else { 114 k -= tmp; 115 lrt = rson[lrt]; 116 rrt = rson[rrt]; 117 l = mid + 1; 118 } 119 } 120 121 return l; 122 } 123 124 int Query_Rank(int rt, int L, int R, int l, int r) { 125 if (L==l && R==r) 126 return c[rt]; 127 128 int mid = (l + r) >> 1; 129 130 if (R <= mid) 131 return Query_Rank(lson[rt], L, R, l, mid); 132 else if (L > mid) 133 return Query_Rank(rson[rt], L, R, mid+1, r); 134 else 135 return Query_Rank(lson[rt], L, mid, l, mid) + Query_Rank(rson[rt], mid+1, R, mid+1, r); 136 } 137 138 void solve() { 139 __int64 ans1 = 0, ans2 = 0, ans3 = 0; 140 int tmp, id; 141 142 sort(a, a+m); 143 m = unique(a, a+m) - a; 144 T[cur] = Build(0, m-1); 145 146 rep(i, 0, q) { 147 if (Q[i].q == 0) { 148 id = lower_bound(a, a+m, Q[i].k) - a; 149 T[cur+1] = Insert(T[cur], id, 1); 150 ++cur; 151 continue; 152 } 153 154 if (Q[i].q == 1) { 155 id = Query_kth(T[Q[i].l-1], T[Q[i].r], Q[i].k); 156 tmp = a[id]; 157 ans1 += tmp; 158 } else if (Q[i].q == 2) { 159 id = lower_bound(a, a+m, Q[i].k) - a; 160 tmp = Query_Rank(T[cur], 0, id, 0, m-1); 161 ans2 += tmp; 162 } else { 163 id = Query_kth(T[0], T[cur], Q[i].k); 164 tmp = a[id]; 165 ans3 += tmp; 166 } 167 168 #ifndef ONLINE_JUDGE 169 // printf("tmp = %d\n", tmp); 170 #endif 171 } 172 173 printf("%I64d\n%I64d\n%I64d\n", ans1, ans2, ans3); 174 } 175 176 int main() { 177 ios::sync_with_stdio(false); 178 #ifndef ONLINE_JUDGE 179 freopen("data.in", "r", stdin); 180 freopen("data.out", "w", stdout); 181 #endif 182 183 int t = 0; 184 char op[16]; 185 186 while (scanf("%d", &q)!=EOF) { 187 init(); 188 rep(i, 0, q) { 189 scanf("%s", op); 190 if (op[0] == 'I') { 191 scanf("%d", &Q[i].k); 192 a[m++] = Q[i].k; 193 Q[i].q = 0; 194 } else if (op[6] == '1') { 195 scanf("%d %d %d", &Q[i].l, &Q[i].r, &Q[i].k); 196 Q[i].q = 1; 197 } else if (op[6] == '2') { 198 scanf("%d", &Q[i].k); 199 Q[i].q = 2; 200 } else { 201 scanf("%d", &Q[i].k); 202 Q[i].q = 3; 203 } 204 } 205 printf("Case %d:\n", ++t); 206 solve(); 207 } 208 209 #ifndef ONLINE_JUDGE 210 printf("time = %d.\n", (int)clock()); 211 #endif 212 213 return 0; 214 }
数据发生器。
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 = 10 10 bound = 10**5 11 for tt in xrange(t): 12 n = randint(200, 300) 13 fout.write("%d\n" % (n)) 14 L = range(1, n+1) 15 shuffle(L) 16 cur = 0 17 has = [] 18 for i in xrange(n): 19 op = randint(0, 3) 20 if cur==0: 21 op=0 22 if op==0: 23 idx = randint(0, len(L)-1) 24 x = L[idx] 25 L.remove(x) 26 has.append(x) 27 cur += 1 28 fout.write("Insert %d\n" % x) 29 elif op==1: 30 l = randint(1, cur) 31 r = randint(l, cur) 32 k = randint(1, r-l+1) 33 fout.write("Query_1 %d %d %d\n" % (l, r, k)) 34 elif op==2: 35 idx = randint(0, len(has)-1) 36 x = has[idx] 37 fout.write("Query_2 %d\n" % x) 38 else: 39 x = randint(1, cur) 40 fout.write("Query_3 %d\n" % x) 41 42 43 def MovDataIn(): 44 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 45 shutil.copyfile("data.in", desFileName) 46 47 48 if __name__ == "__main__": 49 GenDataIn() 50 MovDataIn()