Description
Input
Output
题目大意:给n个数,m次询问区间[l, r]的第k小数。
思路:对询问排序,再离线处理每一个询问(加减点直至平衡树对应区间等于询问区间),不过这样做复杂度是没有保障的……因此差不多的题目如POJ2104妥妥地TLE了……
关于正解之划分树和主席树这里不写。
关于划分树和主席树:
代码(3438MS)(treap树):
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 const int MAXN = 100010; 8 9 int key[MAXN], weight[MAXN], child[MAXN][2], size[MAXN]; 10 int stk[MAXN], top, cnt; 11 12 inline void init() { 13 top = cnt = 0; 14 } 15 16 inline int new_node(int k) { 17 int x = (top ? stk[top--] : ++cnt); 18 key[x] = k; 19 size[x] = 1; 20 weight[x] = rand(); 21 child[x][0] = child[x][1] = 0; 22 return x; 23 } 24 25 inline void update(int &x) { 26 size[x] = size[child[x][0]] + size[child[x][1]] + 1; 27 } 28 29 void rotate(int &x, int t) { 30 int y = child[x][t]; 31 child[x][t] = child[y][t ^ 1]; 32 child[y][t ^ 1] = x; 33 update(x); update(y); 34 x = y; 35 } 36 37 void insert(int &x, int k) { 38 if(x == 0) x = new_node(k); 39 else { 40 int t = key[x] < k; 41 insert(child[x][t], k); 42 if(weight[child[x][t]] < weight[x]) rotate(x, t); 43 } 44 update(x); 45 } 46 47 void remove(int &x, int k) { 48 if(key[x] == k) { 49 if(child[x][0] && child[x][1]) { 50 int t = weight[child[x][0]] < weight[child[x][1]]; 51 rotate(x, t); remove(child[x][t ^ 1], k); 52 } 53 else { 54 stk[++top] = x; 55 x = child[x][0] + child[x][1]; 56 } 57 } 58 else remove(child[x][key[x] < k], k); 59 if(x > 0) update(x); 60 } 61 62 int kth(int &x, int k) { 63 if(x == 0 || k <= 0 || k > size[x]) return 0; 64 int s = 0; 65 if(child[x][0]) s = size[child[x][0]]; 66 if(k == s + 1) return key[x]; 67 if(k <= s) return kth(child[x][0], k); 68 return kth(child[x][1], k - s - 1); 69 } 70 71 struct Node { 72 int l, r, k, id; 73 void read(int i) { 74 id = i; 75 scanf("%d%d%d", &l, &r, &k); 76 } 77 bool operator < (const Node &rhs) const { 78 if(r != rhs.r) return r < rhs.r; 79 return l < rhs.l; 80 } 81 }; 82 83 Node query[MAXN]; 84 int a[MAXN], ans[MAXN]; 85 86 int main() { 87 int n, m; 88 scanf("%d%d", &n, &m); 89 for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); 90 for(int i = 0; i < m; ++i) query[i].read(i); 91 sort(query, query + m); 92 int left = 1, right = 0, root = 0; 93 for(int i = 0; i < m; ++i) { 94 while(right < query[i].r) 95 if(!root) root = new_node(a[++right]); 96 else insert(root, a[++right]); 97 while(left > query[i].l) 98 if(!root) root = new_node(a[--left]); 99 else insert(root, a[--left]); 100 while(left < query[i].l) remove(root, a[left++]); 101 ans[query[i].id] = kth(root, query[i].k); 102 } 103 for(int i = 0; i < m; ++i) printf("%d\n", ans[i]); 104 }