Question link: http://codeforces.com/contest/948/problem/D
Knowledge point: Trie
Topic meaning:
Given two arrays of length \(N(1 \le N \le 300000 )\) \(A\) and \(P(0 \le A_{i},P_{i} \le 2^{30 }\). The array\(P\) can be permuted, and the array is obtained after permutation\(B(B_{i} = A_{i} \oplus P_{i}\), find the array with the smallest lexicographical order\ (B\).
Problem solving ideas:
Treat each number in the arrays \(P\) and \(A\) as a \(31\) digit binary number with leading zeros.
Insert each number in \(P\) into the dictionary tree from high to low.
Traverse each number in \(A\) in turn, query the number in the dictionary tree that is most suitable for XOR with this number (that is, the number with the least different bits in the binary representation and the same high order as possible), and return this number (while in the delete the number from the dictionary).
AC code:
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 const int maxn = 300000+5; 5 int A[maxn]; 6 7 struct Trie{ 8 int ch[maxn*30][3]; 9 int val[maxn*30],nm[maxn*30]; 10 int sz; 11 Trie(){ 12 sz=1; 13 memset(ch[0],0,sizeof(ch[0])); 14 memset(val,0,sizeof(val)); 15 memset(nm,-1,sizeof(nm)); 16 } 17 void inserts(int num){ 18 int u=0; 19 for(int i=30;i>=0;i--){ 20 int nx; 21 if(num&(1<<i)) 22 nx= 1 ; 23 else 24 nx= 0 ; 25 if (! ch[u][nx]){ 26 memset(ch[sz], 0 , sizeof (ch[sz])); 27 ch[u][nx ]= sz; 28 sz++ ; 29 } 30 u= ch[u][nx]; 31 val[u]++; // val records the number of numbers passing through the node 32 } 33 nm[u]=num ; // nm records that the leaf node corresponds to the number 34 } 35 int query( int num){ 36 int u= 0 ; 37 for ( int i= 30 ;i>= 0 ;i-- ){ 38 int nx; 39 if (num&( 1 << i)) 40 nx = 1 ; 41 else 42 nx= 0 ; 43 if (ch[u][nx]&& val[ch[u][nx]]) 44 u=ch[u][nx]; // Make sure the high order bits are the same as possible 45 else 46 u=ch[u][nx^1]; 47 val[u]--; 48 } 49 return nm[u]; 50 } 51 }; 52 Trie ac; 53 int main(){ 54 int N; 55 scanf("%d",&N); 56 for(int i=0;i<N;i++) 57 scanf("%d",&A[i]); 58 int num; 59 for(int i=0;i<N;i++){ 60 scanf("%d",&num); 61 ac.inserts(num); 62 } 63 for(int i=0;i<N;i++){ 64 if(i!=0) printf(" "); 65 printf("%d",ac.query(A[i])^A[i]); 66 } 67 return 0; 68 }