BZOJ 3689 异或之
2016-10-22 10:11
232 查看
TRIE树+堆
如果只求最小的,我们可以建出TRIE树,对每一个数都跑一边求第二小(最小的是自己异或自己),这样一定包含了所有数的异或最小值,然后找最小的即可。
如果还需要求第二小,在排除第一小的情况下,我们把组成第一小的那个数在TRIE树上求一个第三小,这样同样依然包含了所有数的当前异或最小值,以此类推,堆维护即可。
注意a^b = b^a,也就是说一个值会出现两次,所以k应取k*2
如果只求最小的,我们可以建出TRIE树,对每一个数都跑一边求第二小(最小的是自己异或自己),这样一定包含了所有数的异或最小值,然后找最小的即可。
如果还需要求第二小,在排除第一小的情况下,我们把组成第一小的那个数在TRIE树上求一个第三小,这样同样依然包含了所有数的当前异或最小值,以此类推,堆维护即可。
注意a^b = b^a,也就是说一个值会出现两次,所以k应取k*2
#include<cstdio> #include<queue> #include<map> #define N 100005 #define H 30 using namespace std; int a , use ; 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; }
相关文章推荐
- BZOJ[3689] 异或之 Trie树+堆
- BZOJ_3689_异或之_可持久化Trie+堆
- BZOJ 3689 异或之
- BZOJ3689: 异或之
- BZOJ 3689 异或之
- 异或之(bzoj 3689)
- [Trie树] BZOJ3689: 异或之
- 【bzoj3689】【异或之】【trie树+堆】
- bzoj 3689: 异或之
- BZOJ 3689: 异或之 字典树 优先队列
- bzoj 3689: 异或之 字典树+堆
- BZOJ 3689 异或之 Trie树+堆
- BZOJ 3689 异或 Trie木+堆
- 【bzoj3689】异或之 可持久化Trie树+堆
- bzoj 3689 异或之
- 【BZOJ3689】异或之 堆+可持久化Trie树
- BZOJ 3689: 异或之
- BZOJ3689 异或之
- bzoj 3689: 异或之 Trie+堆
- [乱搞 || 可持久化字典树 堆] BZOJ3689 异或之