这个题有点像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; }