Online Judge 2014 K-th Number -主席树

You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment. 
That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?" 
For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.InputThe first line of the input file contains n --- the size of the array, and m --- the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000). 
The second line contains n different integer numbers not exceeding 10 9 by their absolute values --- the array for which the answers should be given. 
The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).OutputFor each question output the answer to it --- the k-th number in sorted a[i...j] segment.

Sample Input

7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3

Sample Output

5
6
3

Hint

This problem has huge input,so please use c-style input(scanf,printf),or you may got time limit exceed.


  很裸的主席树模板题。不知道可不可以用O(n1.5log2n)的莫队加平衡树来做。

  如果用下面这段代码去过poj的话会T掉,如果不是用new动态分配内存而是直接分配一个数组,在数组中储存所有节点可能就可以过了。

Code

  1 /**
  2  * OpenJudge
  3  * Bailian#2104
  4  * Accepted
  5  * Time:2247ms
  6  * Memory:65536k
  7  */
  8 #include<iostream>
  9 #include<fstream>
 10 #include<sstream>
 11 #include<cstdio>
 12 #include<cstdlib>
 13 #include<cstring>
 14 #include<ctime>
 15 #include<cctype>
 16 #include<cmath>
 17 #include<algorithm>
 18 #include<stack>
 19 #include<queue>
 20 #include<set>
 21 #include<map>
 22 #include<vector>
 23 using namespace std;
 24 typedef bool boolean;
 25 #define smin(a, b)    (a) = min((a), (b))
 26 #define smax(a, b)    (a) = max((a), (b))
 27 template<typename T>
 28 inline void readInteger(T& u){
 29     char x;
 30     int aFlag = 1;
 31     while(!isdigit((x = getchar())) && x != '-' && x != -1);
 32     if(x == -1){
 33         ungetc(x, stdin); 
 34         return;
 35     }
 36     if(x == '-'){
 37         x = getchar();
 38         aFlag = -1;
 39     }
 40     for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0');
 41     ungetc(x, stdin);
 42     u *= aFlag;
 43 }
 44 
 45 typedef class SegTreeNode{
 46     public:
 47         int s;    //size
 48         SegTreeNode *left, *right;
 49         SegTreeNode():left(NULL), right(NULL), s(0){        }
 50         void pushUp(){
 51             this->s += this->left->s + this->right->s;
 52         }
 53 }SegTreeNode;
 54 
 55 typedef class SegTree{
 56     public:
 57         SegTreeNode* root;
 58         SegTree():root(NULL){        }
 59         SegTree(int size, int val){
 60             build(root, 1, size, val);
 61         }
 62         SegTree(SegTreeNode* root):root(root){    }
 63         
 64         void build(SegTreeNode*& node, int from, int end, int val){
 65             node = new SegTreeNode();
 66             if(from == end){
 67                 node->s = (val == from) ? (1) : (0);
 68                 return;
 69             }
 70             int mid = (from + end) >> 1;
 71             build(node->left, from, mid, val);
 72             build(node->right, mid + 1, end, val);
 73             node->pushUp();
 74         }
 75 }SegTree;
 76 
 77 typedef class Pair{
 78     public:
 79         int data;
 80         int index;
 81         Pair(const int data = 0, const int index = 0):data(data), index(index){        }
 82         boolean operator < (Pair another) const {
 83             return data < another.data;
 84         }
 85 }Pair;
 86 
 87 typedef class ChairTree{    //主席树
 88     public: 
 89         SegTree* st;
 90         int* discrete;
 91         map<int, int> to;
 92         int len;
 93         ChairTree():st(NULL), discrete(NULL){        }
 94         ChairTree(int* lis, int len):len(len){
 95             discrete = new int[(const int)(len + 1)];
 96             memcpy(discrete, lis, sizeof(int) * (len + 1));
 97             sort(discrete + 1, discrete + len + 1);
 98             for(int i = 1; i <= len; i++)
 99                 to[discrete[i]] = i;
100             st = new SegTree[(const int)(len + 1)];
101             st[0] = SegTree(len, 0);
102             for(int i = 1; i <= len; i++){
103                 st[i] = SegTree();
104                 appendSegTree(st[i].root, st[i - 1].root, 1, len, to[lis[i]]);
105             }
106         }
107         
108         void appendSegTree(SegTreeNode*& node, SegTreeNode*& before, int from, int end, int val){
109             node = new SegTreeNode();
110             if(from == end){
111                 node->s = 1;
112                 return;
113             }
114             int mid = (from + end) >> 1;
115             if(val <= mid){
116                 node->right = before->right;
117                 appendSegTree(node->left, before->left, from, mid, val);
118             }else{
119                 node->left = before->left;
120                 appendSegTree(node->right, before->right, mid + 1, end, val);
121             }
122             node->pushUp();
123         }
124         
125         int query(int l, int r, SegTreeNode*& left, SegTreeNode*& right, int k){
126             if(l == r){
127                 return l;
128             }
129             int ls = left->left->s - right->left->s;
130             int mid = (l + r) >> 1;
131             if(ls >= k)    return query(l, mid, left->left, right->left, k);
132             return query(mid + 1, r, left->right, right->right, k - ls);
133         }
134         
135         int query(int from, int end, int k){
136             return discrete[query(1, len, st[end].root, st[from - 1].root, k)];
137         }
138 }ChairTree;
139 
140 int n, m;
141 ChairTree ct;
142 int *lis;
143 
144 inline void init(){
145     readInteger(n);
146     readInteger(m);
147     lis = new int[(const int)(n + 1)];
148     for(int i = 1; i <= n; i++){
149         readInteger(lis[i]);
150     }
151     ct = ChairTree(lis, n);
152 }
153 
154 inline void solve(){
155     int l, r, k;
156     while(m--){
157         readInteger(l);
158         readInteger(r);
159         readInteger(k);
160         int res = ct.query(l, r, k);
161         printf("%d
", res);
162     }
163 }
164 
165 int main(){
166     init();
167     solve();
168     return 0;
169 }    
原文地址:https://www.cnblogs.com/yyf0309/p/6347884.html