BZOJ 3689 异或之

Posted on 2017-03-09 20:09  ziliuziliu  阅读(208)  评论(0编辑  收藏  举报

这个题有点像HNOI淘金的后半部分。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxn 100050
using namespace std;
int n,k,a[maxn],tree[maxn*32][2],sum[maxn*32],root,tot,s[maxn*10],top=0;
struct status
{
    int val,pos,k;
    status (int val,int pos,int k):val(val),pos(pos),k(k) {}
    status () {}
    friend bool operator < (const status &x,const status &y)
    {
        return x.val>y.val;
    }
};
priority_queue <status> q;
void insert(int &now,int val,int bit)
{
    if (!now) now=++tot;sum[now]++;
    if (bit==-1) return;
    int nb=(val&(1<<bit));
    insert(tree[now][(nb>0)],val,bit-1);
}
int ask(int now,int val,int k,int bit)
{
    if (bit==-1) return 0;
    int nb=val&(1<<bit);
    if (!nb)
    {
        if (sum[tree[now][0]]>=k) return ask(tree[now][0],val,k,bit-1);
        else return ask(tree[now][1],val,k-sum[tree[now][0]],bit-1)+(1<<bit);
    }
    else
    {
        if (sum[tree[now][1]]>=k) return ask(tree[now][1],val,k,bit-1);
        else return ask(tree[now][0],val,k-sum[tree[now][1]],bit-1)+(1<<bit);
    }
}
int main()
{
    scanf("%d%d",&n,&k);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        insert(root,a[i],30);
    }
    for (int i=1;i<=n;i++) q.push(status(ask(root,a[i],2,30),i,2));
    for (int i=1;i<=2*k;i++)
    {
        status now=q.top();q.pop();
        s[++top]=now.val;q.push(status(ask(root,a[now.pos],now.k+1,30),now.pos,now.k+1));
    }
    for (int i=1;i<=2*k;i+=2) printf("%d ",s[i]);
    return 0;
}