BZOJ 3689 异或之
2017-03-09 20:09
260 查看
这个题有点像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; }
相关文章推荐
- BZOJ 3689 异或之 Trie树+堆
- [乱搞 || 可持久化字典树 堆] BZOJ3689 异或之
- 【bzoj3689】【异或之】【trie树+堆】
- BZOJ 3689: 异或之
- BZOJ 3689: 异或之 字典树 优先队列
- BZOJ3689 异或之
- bzoj 3689: 异或之 字典树+堆
- BZOJ 3689: 异或之
- [BZOJ 3689]异或之
- 【bzoj3689】异或之 trie+堆
- BZOJ 3689 异或之
- BZOJ[3689] 异或之 Trie树+堆
- bzoj 3689: 异或之
- BZOJ3689: 异或之
- BZOJ 3689 异或 Trie木+堆
- BZOJ 3689 异或之
- 异或之(bzoj 3689)
- 【bzoj3689】异或之 可持久化Trie树+堆
- BZOJ_3689_异或之_可持久化Trie+堆
- 【BZOJ3689】异或之 堆+可持久化Trie树