zoukankan      html  css  js  c++  java
  • BZOJ 3689: 异或之

    字典树可以$o(logn)查找第k大$

    使用$可持久化Trie 区间查找第k大,然后首先把每个数异或之后的最小丢进小根堆中,然后一个一个取出,取出后就再丢次小,一共取k次$

    总的时间复杂度为$O(klogn)$

    本来的考虑是 先找出第k大,然后在$Trie上DFS把小于这个数的全丢进vector  然后发现会有很多无用状态会搜索到,T掉$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 int n, k, arr[N], kth;
     6 struct node
     7 {
     8     int base, num, pos, l, r;
     9     node () {}
    10     node (int base, int num, int pos, int l, int r) : base(base), num(num), pos(pos), l(l), r(r) {}
    11     bool operator < (const node &r) const { return num > r.num; }
    12 };
    13 priority_queue <node> q;  
    14 
    15 namespace TRIE
    16 {
    17     int rt[N], cnt; 
    18     struct node
    19     {
    20         int son[2], cnt;
    21     }a[N * 50];  
    22     void init()
    23     {
    24         a[1].son[0] = a[1].son[1] = a[1].cnt = 0; 
    25         cnt = 0; 
    26     }  
    27     void insert(int &now, int pre, int x)  
    28     {
    29         now = ++cnt;
    30         a[now] = a[pre];
    31         int root = now; ++a[root].cnt; 
    32         for (int i = 30; i >= 0; --i)
    33         {
    34             int id = (x >> i) & 1; 
    35             a[++cnt] = a[a[root].son[id]]; 
    36             ++a[cnt].cnt;
    37             a[root].son[id] = cnt;
    38             root = cnt;  
    39         }
    40     } 
    41     int find_kth(int x, int k, int l, int r)
    42     {
    43         int res = 0;
    44         int tl = rt[l], tr = rt[r];
    45         for (int s = 30; s >= 0; --s)
    46         {
    47             int id = (x >> s) & 1;
    48             int sum = a[a[tr].son[id]].cnt - a[a[tl].son[id]].cnt;
    49             if (sum < k)
    50             {
    51                 k -= sum;
    52                 res |= 1 << s;
    53                 tr = a[tr].son[id ^ 1];
    54                 tl = a[tl].son[id ^ 1];
    55             }    
    56             else
    57             {
    58                 tr = a[tr].son[id];
    59                 tl = a[tl].son[id]; 
    60             }
    61         }
    62         return res;
    63     }
    64 }
    65 
    66 int main()
    67 {
    68     while (scanf("%d%d", &n, &k) != EOF) 
    69     {
    70         for (int i = 1; i <= n; ++i) scanf("%d", arr + i);
    71         TRIE::init(); 
    72         for (int i = 1; i <= n; ++i) TRIE::insert(TRIE::rt[i], TRIE::rt[i - 1], arr[i]);
    73         for (int i = 1; i < n; ++i) q.push(node(arr[i], TRIE::find_kth(arr[i], 1, i, n), 2, i, n)); 
    74         for (int i = 1; i <= k; ++i)
    75         {
    76             node top = q.top(); q.pop();
    77             printf("%d%c", top.num, " 
    "[i == k]);
    78             q.push(node(top.base, TRIE::find_kth(top.base, top.pos, top.l, top.r), top.pos + 1, top.l, top.r));
    79         }    
    80     }
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    安装pgsql
    ln软连接
    vsftp上传失败
    redis配置systemctl
    jmeter 录制排除模式
    数据库基本操作
    按日期排序
    angularjs的cache
    angularjs路由传递参数
    angularjs路由相关知识
  • 原文地址:https://www.cnblogs.com/Dup4/p/10009756.html
Copyright © 2011-2022 走看看