zoukankan      html  css  js  c++  java
  • BZOJ3689 异或之

    题目描述:

    给定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小的数。

    题解:

    建一棵01Trie树,然后把所有数扔进去。

    将所有数的当前相关最小值插入优先队列,每次弹出来一个。

    因为同一对会出现两次,所以我们只能选取奇数次弹出的点。

    每弹出一个就将相关数的更小值插进去。

    代码:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 100050
    #define ll long long
    inline int rd()
    {
        int f=1,c=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
        return f*c;
    }
    int n,k,a[N],rt[N],sum;
    struct node
    {
        int x;
        ll v;
        node(){}
        node(int x,ll v):x(x),v(v){}
        friend bool operator < (node a,node b)
        {
            return a.v>b.v;
        }
    };
    priority_queue<node>que;
    int dep[N];
    struct Trie
    {
        int tot,siz[35*N],ch[35*N][2];
        void insert(int x)
        {
            int u=1;
            for(int i=30;i>=0;i--)
            {
                int c = (x>>i)&1;
                siz[u]++;
                if(!ch[u][c])ch[u][c]=++tot;
                u=ch[u][c];
            }
            siz[u]++;
        }
        ll query(int x,int k)
        {
            ll ret = 0;
            int u = 1;
            for(int i=30;i>=0;i--)
            {
                int c = (x>>i)&1;
                if(siz[ch[u][c]]>=k)
                {
                    u=ch[u][c];
                }else
                {
                    ret|=(1ll<<i);
                    k-=siz[ch[u][c]];
                    u=ch[u][!c];
                }
            }
            return ret;
        }
    }tr;
    int main()
    {
        n=rd(),k=rd();
        tr.tot=1;
        for(int i=1;i<=n;i++)
        {
            a[i]=rd();
            tr.insert(a[i]);
        }
        for(int i=1;i<=n;i++)
        {
            dep[i]=2;
            ll tmp = tr.query(a[i],2);
            que.push(node(i,tmp));
        }
        for(int i=1;i<=2*k;i++)
        {
            node tp = que.top();
            que.pop();
            if(i&1)printf("%lld ",tp.v);
            dep[tp.x]++;
            if(dep[tp.x]<=n)
            {
                ll tmp = tr.query(a[tp.x],dep[tp.x]);
                que.push(node(tp.x,tmp));
            }
        }
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    Yii框架2.0 数据库操作初接触
    Yii框架2.0的视图和widgets表单的使用
    Yii框架2.0的安装过程
    监控之snmpd 服务
    在HTML里面HEAD部分的META元素要表达的内容是什么
    被table单元格colspan属性折磨了
    excel模版从xp复制到win7系统后出现错误 运行时错误 '429' ActiveX 部件不能创建对象
    oracle左连接连表查询
    Nginx 关闭防火墙
    左连接不能与or否则in连用
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10046267.html
Copyright © 2011-2022 走看看