BZOJ 3689 异或之 (可持久化01Trie+堆)

题目大意:给你一个序列,求出第$K$小的两两异或值

先建出来可持久化$01Trie$

用一个$set$/堆存结构体,存某个异或对$<i,j>$的第二关键字$j$,以及$ai\;xor\;aj$的值,堆中按异或值从小到大排序

每次取出一对$<i,j>$并把它从堆中删除

在$[0,j-1]$的 可持久化$01Trie$ 中把$a_{i}$这个数删除

再查询$[0,j-1]$中和$a_{j}$的异或最大值,重新推入堆中...

反复操作$K$次即可

删除操作中的细节比较多

  1 #include <set>
  2 #include <queue>
  3 #include <vector>
  4 #include <cstdio>
  5 #include <cstring>
  6 #include <algorithm>
  7 #define N1 351000
  8 #define N2 13000000
  9 #define MM 100
 10 #define ll long long
 11 #define dd double  
 12 #define uint unsigned int
 13 #define mod 1000000007
 14 #define idx(X) (X-'a')
 15 #define it multiset<node>::iterator
 16 using namespace std;
 17 
 18 uint bin[35];
 19 struct Trie{
 20 int ch[N2][2],num[N2],root[N1],tot;
 21 void init()
 22 {
 23     root[0]=tot=1;int x=1;
 24     for(int i=31;i>=0;i--){
 25         ch[x][0]=++tot;
 26         x=ch[x][0],num[x]=1;
 27     }
 28 }
 29 void insert(uint s,int rt1,int rt2,int w)
 30 {
 31     int x,y,p;
 32     y=root[rt1];
 33     x=root[rt2]=++tot;
 34     for(int i=31;i>=0;i--)
 35     {
 36         p=(s&bin[i])?1:0;
 37         ch[x][p]=++tot;
 38         ch[x][p^1]=ch[y][p^1];
 39         num[ch[x][p]]=num[ch[y][p]]+w;
 40         x=ch[x][p],y=ch[y][p];
 41     }
 42 }
 43 uint query(uint s,int l,int r)
 44 {
 45     int x,y,p;uint ans=0;
 46     x=root[r],y=l<0?0:root[l];
 47     for(int i=31;i>=0;i--)
 48     {
 49         p=(s&bin[i])?1:0;
 50         if(num[ch[x][p]]-num[ch[y][p]]>0){
 51             x=ch[x][p],y=ch[y][p];
 52         }else if(num[ch[x][p^1]]-num[ch[y][p^1]]>0){
 53             x=ch[x][p^1],y=ch[y][p^1];
 54             ans|=bin[i];
 55         }else break;
 56     }return ans;
 57 }
 58 }T;
 59 
 60 int n,K;
 61 int a[N1],res[N1];
 62 struct node{
 63     int id;uint val;
 64     friend bool operator < (const node &s1,const node &s2){
 65         if(s1.val!=s2.val)
 66             return s1.val<s2.val;
 67         else 
 68             return s1.id<s2.id;
 69     }
 70     node(int id,uint val):id(id),val(val){}
 71     node(){}
 72 };
 73 multiset<node>s;
 74 
 75 int main()
 76 {
 77     //freopen("t1.in","r",stdin);
 78     scanf("%d%d",&n,&K);
 79     for(int i=0;i<=31;i++)
 80         bin[i]=(1<<i);
 81     T.init();uint x;
 82     for(int i=1;i<=n;i++){
 83         scanf("%d",&a[i]);
 84         T.insert(a[i],i-1,i,1);
 85     }
 86     for(int i=2;i<=n;i++){
 87         x=T.query(a[i],0,i-1);
 88         s.insert(node(i,x));
 89         res[i]=i-1;
 90     }
 91     node p;int i,w;
 92     for(int k=1;k<=K;k++){
 93         it t=s.begin();
 94         w=(*t).val,i=(*t).id;
 95         printf("%u\n",w);
 96         T.insert(w^a[i],i-1,i-1,-1);
 97         w=T.query(a[i],0,i-1);
 98         s.erase(t++);res[i]--;
 99         if(res[i]) s.insert(node(i,w));
100     }
101     return 0;
102 }

 

posted @ 2018-11-27 19:41  guapisolo  阅读(170)  评论(0编辑  收藏  举报