可持久化线段树是可以查询历史版本的数据结构,比如说查询区间第k大的数,那么我们需要查询到1-r 和 1- (l - 1) 数据的分布情况,以完成查询。
2015年11月25日
模板题 poj2104
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define rep(i, a, b) for (int i = a; i <= b; i++) 5 #define REP(i, a, b) for (int i = a; i < b; i++) 6 #define drep(i, a, b) for (int i = a; i >= b; i--) 7 #define mp make_pair 8 #define pb push_back 9 #define clr(x) memset(x, 0, sizeof(x)) 10 #define xx first 11 #define yy second 12 using namespace std; 13 typedef long long i64; 14 typedef pair<int, int> pii; 15 const int inf = ~0U>>1; 16 const i64 INF = ~0ULL >> 1; 17 //********************************* 18 19 const int maxn = 100005, maxm = 2060965; 20 int Sum[maxm]; 21 int Lson[maxm], Rson[maxm]; 22 23 int read() { 24 int l = 1, s = 0; 25 char ch = getchar(); 26 while (ch < '0' || ch > '9') { if (ch == '-') l = -1; ch = getchar(); } 27 while (ch >= '0' && ch <= '9') { s = (s << 1) + (s << 3) + ch - '0'; ch = getchar(); } 28 return l * s; 29 } 30 31 int totnode; 32 void build(int x, int &y, int l, int r, int v) { 33 Sum[y = ++totnode] = Sum[x] + 1; 34 if (l == r) return; 35 int mid = l + r >> 1; 36 if (v <= mid) { 37 Rson[y] = Rson[x]; 38 build(Lson[x], Lson[y], l, mid, v); 39 } 40 else { 41 Lson[y] = Lson[x]; 42 build(Rson[x], Rson[y], mid + 1, r, v); 43 } 44 } 45 46 int query(int x, int y, int l, int r, int k) { 47 if (l == r) return l; 48 int mid = l + r >> 1, tmp = Sum[Lson[y]] - Sum[Lson[x]]; 49 if (tmp >= k) return query(Lson[x], Lson[y], l, mid, k); 50 else return query(Rson[x], Rson[y], mid + 1, r, k - tmp); 51 } 52 53 int val[maxn], hsh[maxn], root[maxn]; 54 int main() { 55 int n, m; 56 n = read(), m = read(); 57 rep(i, 1, n) val[i] = read(), hsh[i] = val[i]; 58 sort(hsh + 1, hsh + 1 + n); int cd = unique(hsh + 1, hsh + 1 + n) - (hsh + 1); 59 rep(i, 1, n) val[i] = lower_bound(hsh + 1, hsh + 1 + cd, val[i]) - hsh; 60 61 int cnt = cd; 62 for (int i = 1; i <= n; i++) 63 build(root[i - 1], root[i], 1, cnt, val[i]); 64 65 for (int i = 1; i <= m; i++) { 66 int x, y, k; x = read(), y = read(), k = read(); 67 printf("%d\n", hsh[query(root[x - 1], root[y], 1, cnt, k)]); 68 } 69 70 return 0; 71 }