1. 程式人生 > 實用技巧 >CF 1416C XOR Trie

CF 1416C XOR Trie

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define rg register
 4 using namespace std;
 5 const int N = 6e6 + 10;
 6 int a[N];
 7 int t[N][2], cnt = 0;
 8 vector<int> v[N];
 9 ll dp[30][2];
10 
11 void Insert(int x, int pos)
12 {
13     int root = 0;
14     for(rg int i = 29 ; i >= 0
; i--){ 15 int now = ((x >> i) & 1); 16 if(!t[root][now]){ 17 t[root][now] = ++cnt; 18 } 19 root = t[root][now]; 20 v[root].push_back(pos); 21 } 22 } 23 24 void solve(int root, int now) 25 { 26 int lson = t[root][0], rson = t[root][1
]; 27 if(lson) solve(lson, now - 1); 28 if(rson) solve(rson, now - 1); 29 if(!lson || !rson) return ; 30 31 ll t = 0; 32 ll sum = 0; 33 for(auto x : v[lson]){ 34 while(t < (ll)v[rson].size() && x > v[rson][t]) t++; 35 sum += t; 36 }
37 dp[now][0] += sum; 38 dp[now][1] += (ll)v[lson].size() * 1ll * (ll)v[rson].size() - sum; 39 } 40 41 int main(){ 42 int n;scanf("%d",&n); 43 for(rg int i = 1 ; i <= n ; i++){ 44 scanf("%d",&a[i]); 45 Insert(a[i], i); 46 } 47 solve(0, 29); 48 49 ll inv = 0, X = 0; 50 for(int i = 0 ; i <= 29 ; i++){ 51 if(dp[i][0] > dp[i][1]){ 52 X += (1 << i); 53 inv += dp[i][1]; 54 }else{ 55 inv += dp[i][0]; 56 } 57 } 58 printf("%lld %lld\n", inv, X); 59 return 0; 60 }