我们需要知道一个事实,trie树上是可以要求第k大的!

我们每个节点记个size值然后像其他数据结构一样维护就可以了

然后我们再搞个priority_queue什么的就好了,注意每个值会出现两次只要记一次

 

  1 /**************************************************************
  2     Problem: 3689
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:4328 ms
  7     Memory:44524 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <queue>
 12  
 13 using namespace std;
 14 const int N = 1e5 + 5;
 15 const int Tot_sz = N * 35;
 16  
 17 struct trie_node {
 18     trie_node *son[2];
 19     int sz;
 20 } *null, *trie_root, mempool[Tot_sz], *cnt_trie = mempool;
 21  
 22 struct data {
 23     int x, y, k;
 24     data() {}
 25     data(int _x, int _y, int _k) : x(_x), y(_y), k(_k) {}
 26      
 27     inline bool operator < (const data &a) const {
 28         return x == a.x ? (y == a.y ? k > a.k : y > a.y) : x > a.x;
 29     }
 30 };
 31  
 32 int n, m;
 33 int a[N];
 34 priority_queue <data> h;
 35  
 36 inline int read() {
 37     int x = 0;
 38     char ch = getchar();
 39     while (ch < '0' || '9' < ch)
 40         ch = getchar();
 41     while ('0' <= ch && ch <= '9') {
 42         x = x * 10 + ch - '0';
 43         ch = getchar();
 44     }
 45     return x;
 46 }
 47  
 48 #define Son p -> son
 49 #define Sz p -> sz
 50 inline void trie_null(trie_node *&p) {
 51     p = cnt_trie;
 52     Son[0] = Son[1] = p;
 53     Sz = 0;
 54 }
 55  
 56 inline void trie_new(trie_node *&p) {
 57     p = ++cnt_trie, *p = *null;
 58 }
 59  
 60 inline void trie_insert(int x) {
 61     static trie_node *p;
 62     static int i, t;
 63     for (p = trie_root, ++Sz, i = 30; ~i; --i) {
 64         t = x >> i & 1;
 65         if (Son[t] == null) trie_new(Son[t]);
 66         p = Son[t], ++Sz;
 67     }
 68 }
 69  
 70 inline int trie_query(int x, int rank) {
 71     static trie_node *p;
 72     static int i, t, res;
 73     for (p = trie_root, i = 30, res = 0; ~i; --i) {
 74         t = x >> i & 1;
 75         if (rank <= Son[t] -> sz) p = Son[t];
 76         else {
 77             rank -= Son[t] -> sz;
 78             res |= 1 << i;
 79             p = Son[!t];
 80         }
 81     }
 82     return res;
 83 }
 84 #undef Son
 85 #undef Sz
 86  
 87 int main() {
 88     int i, x, y, k;
 89     n = read(), m = read();
 90     trie_null(null);
 91     trie_new(trie_root);
 92     for (i = 1; i <= n; ++i) {
 93         a[i] = read();
 94         trie_insert(a[i]);
 95     }
 96     for (i = 1; i <= n; ++i)
 97         h.push(data(trie_query(a[i], 2), a[i], 2));
 98     for (i = 1; i < 2 * m; ++i) {
 99         x = h.top().x, y = h.top().y, k = h.top().k;
100         if (i & 1) {
101             if (i != 1) putchar(' ');
102             printf("%d", x);
103         }
104         h.pop();
105         h.push(data(trie_query(y, k + 1), y, k + 1));
106     }
107     return 0;
108 }
View Code

(p.s. 注意会PE...然后改了一下输出边WA了QAQ...第三次才改对...)

posted on 2015-03-20 23:10  Xs酱~  阅读(345)  评论(0编辑  收藏  举报