XOR (data dictionary)

Topic description

Given an integer m and the numbers A1, A2, ..An of n, XOR all the elements in the sequence A in pairs, and get n(n-1)/2 results in total, and ask for any of the results greater than m. how many.

Enter description:

The first line contains two integers n,m. 
The second line gives n integers A1,A2,...,An.
Data range
For 30% of the data, 1 <= n, m <= 1000
For 100% of the data, 1 <= n, m, Ai <= 10^5

Output description:

The output consists of only one line, the answer sought
Example 1

enter

3 10  
6 5 10

output

2
  1  import java.sql.Time;
   2  import java.util.ArrayList;
   3  import java.util.List;
   4  import java.util.Scanner;
   5  
  6  /** 
  7  Ideas: Direct calculation must be timed out, so this problem Can't use brute force cracking, considering that the bit operations are performed in sequence from the high order to the position,
   8  * If the XOR result of two numbers is 1 in a certain high order, and the corresponding bit of m is 0, then the XOR result of any of these two bits is sure to be 1 will be larger than m.
  9  * Therefore, consider using a dictionary tree (TrieTree) to build a dictionary from high to low, and then use each element to go to the dictionary in turn to check the number of the corresponding high-order XOR is 1,
 10  * and m is 0, add the number of numbers Dividing by 2 is the final result; directly post the code as follows, non-original, welcome to discuss;
 11  * Supplement: queryTrieTree searches from high to low during the search process, then, if there is a number and the number in the dictionary If the kth bit of the XOR result
 12  * is greater than the kth bit of m, then the XOR result of this number and all the numbers in the corresponding branch will be greater than m, otherwise, it is necessary to search for the XOR
 13 in the kth bit * In the case of equality, the XOR result of the lower bits. The functions of the four branches in queryTrieTree are as follows:
 14  1. When aDigit=1, mDigit=1, the kth bit in the dictionary is 0, the XOR result is 1, and the lower bit needs to be searched, the kth bit is 1, XOR The result is 0, less than mDigit, ignore it;
 15  2. When aDigit=0, mDigit=1, the k-th bit in the dictionary is 1, and the XOR result is 1, and it is necessary to continue searching for lower bits, the k-th bit is 0, XOR The result is 0, less than mDigit, ignore it; 
 16  3. When aDigit=1, mDigit=0, the kth bit in the dictionary is 0, the XOR result is 1, and the XOR with all numbers of the corresponding branch, the result will be greater than m, the The k bit is 1, the XOR result is 0, and the result is obtained recursively;
 17  4. When aDigit=0, mDigit=0, the kth bit in the dictionary is 1, the XOR result is 1, and the XOR with all the numbers of the corresponding branch, the result All are greater than m, the kth bit is 0, the XOR result is 0, and the result is obtained recursively;
 18  * Improvement: 
 19  1. The 17-bit dictionary tree can be guaranteed to be greater than 100000, and the shift range is 1~16 bits, then the dictionary tree is constructed From 16 to 0, the first layer of the dictionary tree does not occupy space. In fact, there is data in layers 15 to -1, which is also the usage of next in the data. 2. The queryTrieTree function needs to take into account the return value when the index is -1.
20   
21  Time complexity: O(n); Space complexity O(k), k is a constant (height of the trie tree), so it can be considered O(1). XOR
 22  * 
 23  *@author Dell
 24  *
 25   */ 
26  public  class Main {
 27  private     static  class TrieTree {
 28          TrieTree[] next = new TrieTree[2]; // Place child nodes 
29          int count = 1; // Record the way through this road number of elements 
30      }
 31      public  static  void main(String[] args) {
 32  
33          Scanner sc = new Scanner(System.in);
 34          while (sc.hasNext()) {
 35             int n = sc.nextInt();
 36             int m = sc.nextInt();
 37             int[] a = new int[n];
 38             for (int i = 0; i < n; i++) {
 39                 a[i] = sc.nextInt();
 40             }
 41             System.out.println(solver(a, m));
 42         }
 43     }
 44     static private long solver(int[] a, int m) {
 45         TrieTree tree = setTrieTree(a);
 46         long result = 0;
 47         for (int i = 0; i < a.length; i++) {
 48             result += queryTrieTree(tree, a[i], m, 31);
 49         }
 50 
 51         return result / 2;
 52     }
 53     static private long queryTrieTree(TrieTree tree, int a, int m, int index/* 用于记录查找的层数 */) {
 54         if (tree == null) {
55              return 0; // Exit recursion 
56          }
 57          TrieTree curTree = tree;
 58  
59          // Continue to search downward when the loop is used for this layer and no result is obtained 
60          for ( int i = index; i >= 0; i- - ) {
 61              int aDigit = (a >> i) & 1; // i continues to search down on the basis of index, and each time it takes 1 digit 
62              int mDigit = (m >> i) & 1 ;
 63              // Because the first layer of the dictionary tree does not contain characters, aDigit is directly XORed with the characters in next, which is the subscript
 64 in the next layer of this layer              // So it has been specified when taking next[0] next[1] The value of k bits is
 65              // that is, the data of k+1 bits when compared when the tree is at the k level
66              if (aDigit == 1 && mDigit == 1 ) {
 67                  if (curTree.next[0] == null ) { // 1^0=1 can make am equal temporarily and we need to verify next within our statistical range [0] 
68                      return 0; // There is no way to exit when encountering null 
69                  }
 70                  // 1^1 = 0 a<m does not meet the conditions to exit 
71                  curTree = curTree.next[0 ];
 72              } else  if (aDigit == 0 && mDigit == 1) { // 0^1=1 to make am equal, we still need to verify next[1] 
73                  if (curTree.next[1] == null ) {
 74                     return 0; // There is no way to exit 
75                  }
 76                  // 0^0=0 a<m does not meet the conditions to exit 
77                  curTree = curTree.next[1 ];
 78              } else  if (aDigit == 1 && mDigit = = 0 ) {
 79                  long p = queryTrieTree(curTree.next[1], a, m, i - 1); // 1^1=0 am equal continue to verify 
80                  long q = curTree.next[0] == null ? 0 : curTree.next[0].count; // 1^0=1 a>m directly take the result 
81                  return p + q;
 82              } else if (aDigit == 0 && mDigit == 0 ) {
 83                  long p = queryTrieTree(curTree.next[0], a, m, i - 1); // 0^0=0 am equal continue to verify 
84                  long q = curTree.next[1] == null ? 0 : curTree.next[1].count; // 0^1=1 a>m directly take the result 
85                  return p + q;
 86              }
 87          }
 88  
89          return 0 ;
 90      }
 91      static  public TrieTree setTrieTree( int [] a) {
 92          TrieTree tree = new TrieTree();
 93         for (int i = 0; i < a.length; i++) {
 94             TrieTree curTree = tree;
 95             for (int j = 31; j >= 0; j--) {
 96                 int aDigit = (a[i] >> j) & 1;
 97                 if (curTree.next[aDigit] == null) {
 98                     curTree.next[aDigit] = new TrieTree();
 99                 } else {
100                     curTree.next[aDigit].count++;
101                 }
 102  
103                  curTree = curTree.next[aDigit]; // Next level 
104              }
 105          }
 106          return tree;
 107  }
 108 }

 

 

Guess you like

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