CF948D Perfect Security

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 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325172273&siteId=291194637