1. 程式人生 > >BZOJ 3689 異或之 (可持久化01Trie+堆)

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 }