"Blue Bridge Cup Daily Question" trie tree · 143. The largest XOR pair

  1. topic description

Select two of the given N integers A 1 , A 2 ... A N for xor (exclusive OR) operation, what is the maximum result obtained?

input format

The first line enters an integer N.

The second line inputs N integers A 1 to A N .

output format

Output an integer representing the answer.

data range

1≤N≤105,

0≤Ai<231

Input sample:

3
1 2 3

Sample output:

3

2. Thinking analysis

Pick two numbers from the array. These two numbers must satisfy the XOR result to be the largest.

Violent enumeration O(n2)O(n2) Enumerate these two numbers at a time to take the XOR maximum value

Trie tree optimization O(n∗31)O(n∗31)

For a certain number A, another number that can be XORed with it to get a larger result is recorded as B

Then when the higher digits of A and B are different, the XOR result will be larger

what do you mean give me an example

A = 1010, B = 1111 The highest different bit in the binary representation of AB is the third bit from the right. At this time, the XOR result is A^B=0101

A = 1010, B = 0011 The highest different bit in the binary representation of AB is the fourth bit from the right. At this time, the XOR result is A^B=1001

Obviously at this time B=0011 is what we need

If there is another B so that the different digit is also the fourth from the right, then see who is higher in the next different digit

A=1010, B=0111 Observe that the second highest different bit is the third from the right, and the XOR result is A^B=1101

And the second highest different bit of B=0011 is the second from the right, and the XOR result is A^B=1001

Obviously at this time a new B must be selected B=0111

The above is just the principle code. How to realize it? Here it depends on the Trie tree

Choose a number A each time and then find another number B that can form the largest XOR sum with it from the recorded numbers

1. According to the binary representation of A, traverse from high to low

2. Each time in the tree, look for the different numbers representing the number at this position (I don’t know what name to choose, if a certain bit of A is 1, look for 0, if it is 0, look for 1)

3. If there happens to be a record of "different numbers at this position" in the tree, then move to the corresponding subtree and continue to judge the next position

4. But if there is no "number different at this position" recorded in the tree (that is, all numbers are the same as A at this position), then it has to be forced to move to the corresponding subtree

5. Traverse to the 0th position (that is, the leaf node) to find the number B we need

Remember XOR and bit res Initially res = 0

When there are different numbers in a certain position, the result of XOR completion of this position must be 1, so res = (res << 1) + 1

If there are no different numbers and we have to choose the same one, then the result of XOR at this position must be 0, so res = (res << 1) + 0

Until the leaf node res is traversed, it is the maximum XOR sum that A can obtain

3.Ac code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static int M=31,N=31*100010,idx=0;
    static int[][] trie=new int[N][2];
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        int n=Integer.parseInt(br.readLine());
        String []s=br.readLine().split(" ");
        for (int i = 1; i <=n; i++) {
            insert(Integer.parseInt(s[i-1]));
        }
        int ans=-1;
        for (int i = 1; i <=n; i++) {
            int t=Integer.parseInt(s[i-1]);
            ans=Math.max(ans,query(t));
        }
        System.out.println(ans);

    }

    private static int query(int x) {
        int t=0,res=0;
        for(int i=M-1;i>=0;i--){
            int k=((x>>i)&1)^1;   //因为要找的是相反的数,所以异或一下
            if(trie[t][k]!=0){   //如果存过相反的,那么更新一下res并到下一节点
                t=trie[t][k];
                res=(res << 1) + 1;
            }else {
                t=trie[t][k^1];
                res<<=1;
            }
        }
        return res;
    }

    private static void insert(int x) {
        int t=0;
        for(int i=M-1;i>=0;i--){
            int k=(x>>i) &1;   // 取得第i位上的数  (这里i从右往左 从0开始)
            //如果没有创建过,那么先存进去
            if(trie[t][k]==0)  trie[t][k]=++idx;
            t=trie[t][k];  // 移到下一节点
        }
    }

}
Thank you for reading it. If you have any mistakes, please comment and correct me. If you have a good idea, you can communicate. If it is helpful to you, please like it and support it.

Guess you like

Origin blog.csdn.net/m0_68055637/article/details/129218965