Codeforces 1285D (01 dictionary tree for exclusive or maximum value)

D. Dr. Evil Underscores

Question portal:

Dr. Evil Underscores

Main idea:

Give you n integers, and then choose a number X to make the maximum value after aixor X the smallest, and find the minimum.

Ideas:

When I first saw this word for the maximum value of XOR, I instinctively thought about it in the direction of the dictionary tree. The first thing I thought was to use each number and other numbers to XOR, and then take the minimum value, but the complexity of n^2 will definitely time out.

Then after thinking for a while, when a bit of binary is all 0 or 1, the corresponding position of x should be the same as them, so that the final answer can be minimized. The key is how to consider when there are both 1 and 0 in this bit binary. My initial thought was that when the current digit has 1 and 0, it must be 1 after the exclusive OR. Just take a number for the current digit and add it directly. But this will not work, for example:
0 * * * * *
1 * * * * *
When the first digit is XORed with 0, no matter what the asterisk represents, the second number is definitely higher than the first one. If the number is large, then there is no need to continue discussing the first number, and the numbers after the first number do not produce any effective contribution. This is of course wrong.

So we can think of traversing from left to right according to the binary system. If it is all 0 or 1, the current bit contributes +0 and continues to traverse to the next bit. If the current bit has 0 and 1, then it is divided into two sets. Solve the sub-sets separately, then select the better set and add the contribution of the current position. This is obviously a recursive process.

AC Code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e5+10;
LL a[N],sum=0;
int tot=0;
int tries[N*30][2];
void insert(LL x)
{
    
    
    int u=0;
    for(int i=29;i>=0;i--)
    {
    
    
        int v=(x>>i)&1;
        if(tries[u][v]==0) tries[u][v]=++tot;
        u=tries[u][v];
    }
}
LL dfs(int idx,int pos)
{
    
    
    if(pos==-1) return 0;
    if(tries[idx][0]==0) return dfs(tries[idx][1],pos-1);
    else if(tries[idx][1]==0) return dfs(tries[idx][0],pos-1);
    else return (1<<pos)+min(dfs(tries[idx][0],pos-1),dfs(tries[idx][1],pos-1));
}
int main()
{
    
    
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
    
    
        scanf("%lld",&a[i]);
        insert(a[i]);
    }
    LL maxn=dfs(0,29);
    printf("%lld\n",maxn);
    //system("pause");
    return 0;
}

Guess you like

Origin blog.csdn.net/Stevenwuxu/article/details/109692791