# BZOJ 3689 异或之

TRIE树+堆

#include<cstdio>
#include<queue>
#include<map>
#define N 100005
#define H 30
using namespace std;
int a[N], use[N];

map<pair<int,int>,bool> vis;

int nodecnt;
struct node
{
node *ch[2];
int siz;
node(){ch[0]=ch[1]=NULL;siz=0;}
}s[N*50];

struct TRIE
{
node *root;
void init()
{
root = &s[++nodecnt];
}
void insert(int x)
{
node *p = root;
for(int i = H, pos = 1<<H; ~i; i--, pos>>=1)
{
if(!p->ch[0])p->ch[0]=&s[++nodecnt];
if(!p->ch[1])p->ch[1]=&s[++nodecnt];
int son = x&pos?1:0;
p=p->ch[son];
p->siz++;
}
}
int find(int x, int k)//第k小
{
node *p = root;
int ret = 0;
for(int i = H, pos = 1<<H; ~i; i--, pos>>=1)
{
int son = x&pos?1:0;
if(p->ch[son]->siz >= k)
{
ret<<=1;
p=p->ch[son];
}
else
{
ret<<=1;
ret|=1;
k-=p->ch[son]->siz;
p=p->ch[son^1];
}
}
return ret;
}
}trie;

struct number
{
int x, v;
number(int a, int b):x(a),v(b){}
friend bool operator < (number a, number b)
{
return a.v>b.v;
}
};

int main()
{
int n, k;
scanf("%d%d",&n,&k);
trie.init();
for(int i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
trie.insert(a[i]);
use[i]=1;
}

priority_queue<number> q;

for(int i = 1; i <= n; i++)
{
++use[i];
int num = trie.find(a[i],use[i]);
q.push(number(i,num));
}

for(int i = 1, ii = 2*k; i < ii; i++)
{
number x = q.top(); q.pop();
if(i&1)printf("%d ",x.v);
int pos = x.x, num;

if(use[pos]==n)continue;
use[pos]++;
num = trie.find(a[pos],use[pos]);
q.push(number(pos,num));
}
return 0;
}