[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;
}