[CF1416C] XOR Inverse

[CF1416C] XOR Inverse - Trie

Description

给定长度为 (n) ((1le nle3 imes 10^5)) 的数列 ({a_n}) ((0le a_nle 10^9)),请求出最小的整数 (x) 使 ({a_noplus x}) 的逆序对数最少。

Solution

对于任意两个数,如果他们不同,那么一定存在一个最高的位 i,使得 i+1,i+2,...,M-1 位都相同,但 i 位不同

对于每两个数,我们都找到这样的最高位 k,并把第 k 位是 0 的那个数记作前项,是 1 的那个数记作后项,构成有序对 (i,j)

如果 (i>j) 的个数多于 (i<j) 的个数,那么 x 的这一位填 1,否则填 0

用 trie 树来统计即可

#include <bits/stdc++.h>
using namespace std;

#define int long long 
const int N = 1e7+5;

int n;
int a[N];
int siz[N];
int ch[N][2];
int cnt[33][2];
int ind,x,ans;

signed main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        int p=0;
        for(int j=30;j>=0;j--)
        {
            int c=(a[i]>>j)&1;
            cnt[j][c]+=siz[ch[p][c^1]];
            if(ch[p][c]==0) ch[p][c]=++ind;
            siz[ch[p][c]]++;
            p=ch[p][c];
        }
    }
    for(int i=0;i<=30;i++)
    {
        ans+=min(cnt[i][0],cnt[i][1]);
        if(cnt[i][1]<cnt[i][0]) x+=1<<i;
    }
    cout<<ans<<" "<<x<<endl;
}

原文地址:https://www.cnblogs.com/mollnn/p/14465606.html