zoukankan      html  css  js  c++  java
  • 异或之(bzoj 3689)

    Description

    给定n个非负整数A[1], A[2], ……, A[n]。
    对于每对(i, j)满足1 <= i < j <= n,得到一个新的数A[i] xor A[j],这样共有n*(n-1)/2个新的数。求这些数(不包含A[i])中前k小的数。
    注:xor对应于pascal中的“xor”,C++中的“^”。

    Input

    第一行2个正整数 n,k,如题所述。
    以下n行,每行一个非负整数表示A[i]。

    Output

     共一行k个数,表示前k小的数。

    Sample Input

    4 5
    1
    1
    3
    4

    Sample Output

    0 2 2 5 5

    HINT

    【样例解释】

    1 xor 1 = 0 (A[1] xor A[2])

    1 xor 3 = 2 (A[1] xor A[3])

    1 xor 4 = 5 (A[1] xor A[4])

    1 xor 3 = 2 (A[2] xor A[3])

    1 xor 4 = 5 (A[2] xor A[4])

    3 xor 4 = 7 (A[3] xor A[4])

    前5小的数:0 2 2 5 5

    【数据范围】

     对于100%的数据,2 <= n <= 100000; 1 <= k <= min{250000, n*(n-1)/2};

            0 <= A[i] < 2^31

    /*
      由于trie数可以去出某个数与一坨数第k异或值,我们把每个数二进制拆分,用trie树储存起来。
      维护一个堆,刚开始把每个数与其他数的第二小异或值放进去(第一小是与它本身),然后每次从堆中取数,再把取出来的数的下一个最小值放进去,因为每个异或值会被重复取两次,所以选择奇数次输出。 
    */
    #include<cstdio>
    #include<iostream>
    #include<queue>
    #define N 100010
    using namespace std;
    int a[N],ch[N*30][3],size[N*30],n,k,cnt;
    struct node{
        int v,a,k;
    };
    bool operator < (node s1,node s2){
        return s1.v>s2.v;
    }
    priority_queue<node> q;
    void insert(int x){
        int now=0;
        for(int i=30;i>=0;i--){
            int t=x&(1<<i);t>>=i;
            if(!ch[now][t])ch[now][t]=++cnt;
            now=ch[now][t];size[now]++;
        }
    }
    int query(int x,int k){
        int now=0,tmp=0;
        for(int i=30;i>=0;i--){
            int t=x&(1<<i);t>>=i;
            if(size[ch[now][t]]>=k)now=ch[now][t];
            else k-=size[ch[now][t]],now=ch[now][t^1],tmp+=(1<<i);
        }
        return tmp;
    }
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            insert(a[i]);
        }
        for(int i=1;i<=n;i++){
            node x;
            x.v=query(a[i],2);x.k=2;x.a=a[i];
            q.push(x);
        }
        for(int i=1;i<k*2;i++){
            node x=q.top();q.pop();
            if(i&1)printf("%d ",x.v);
            x.k++;x.v=query(x.a,x.k);
            q.push(x);
        }
        return 0;
    }
  • 相关阅读:
    异常处理 Exception
    C#使用SQLite出错:无法加载 DLL“SQLite.Interop.dll”,找不到指定的模块
    NullableKey:解决Dictionary中键不能为null的问题 zt
    STSdb
    C# 如何获取某个类型或类型实例对象的大小
    CORREL
    C# 深复制
    mysql数据库创建函数过程
    mysql 数据库怎样快速的复制表以及表中的数据
    代码优化(一)
  • 原文地址:https://www.cnblogs.com/harden/p/6246488.html
Copyright © 2011-2022 走看看