平衡树

 

 

 1 // Persistant segment tree
 2 struct Node {
 3     int val;
 4     Node *ch[2];
 5 };
 6 
 7 int a[maxn], n;
 8 Node *root[maxn];
 9 
10 Node* sgtIns(Node* q, int pos) { // 在q的基础上将pos这个位置的数+1, 并返回一个新的线段树的根
11     int l = 0, r = n;
12     Node *s = new Node, *p = s;
13     while (l < r) {
14         p->val = q ? q->val + 1 : 1;
15         int mid = (l + r)>> 1;
16         if (pos <= mid) {
17             p->ch[1] = q ? q->ch[1] : 0;
18             p = p->ch[0] = new Node;
19             q = q ? q->ch[0] : 0;
20             r = mid;
21         } else {
22             p->ch[0] = q ? q->ch[0] : 0;
23             p = p->ch[1] = new Node;
24             q = q ? q->ch[1] : 0;
25             l = mid + 1;
26         }
27     }
28     p->val = q ? q->val + 1 : 1;
29     return s;
30 }
31 
32 int sgtKth(Node* p, Node* q, int k) {
33     int l = 0, r = n;
34     while (l < r) {
35         int cntleft = (q && q->ch[0] ? q->ch[0]->val : 0) - (p && p->ch[0] ? p->ch[0]->val : 0);
36         int mid = (l + r)>> 1;
37         if (cntleft >= k) {
38             r = mid;
39             p = p ? p->ch[0] : 0;
40             q = q ? q->ch[0] : 0;
41         } else {
42             k -= cntleft;
43             l = mid + 1;
44             p = p ? p->ch[1] : 0;
45             q = q ? q->ch[1] : 0;
46         }
47     }
48     return l;
49 }
50 
51 int main() {
52     cin >> n;
53     for (int i = 1; i <= n; ++ i) {
54         cin >> a[i];
55     }
56     root[0] = 0;
57     for (int i = 1; i <= n; ++ i) {
58         root[i] = sgtIns(root[i - 1], a[i]);
59     }
60     int q;
61     cin >> q;
62     while (q --) {
63         int l, r, k;
64         cin >> l >> r >> k;
65         cout << sgtKth(root[l - 1], root[r], k) << endl;
66     }
67 }

 

posted @ 2017-01-23 15:49  InWILL  阅读(143)  评论(0编辑  收藏  举报