1. 程式人生 > 其它 >C. XOR Inverse 題解(字典樹求逆序對)

C. XOR Inverse 題解(字典樹求逆序對)

題目連結

題目思路

字典樹居然還能求逆序對,震驚

就是利用字典樹求逆序對的思想來解決此題

妙蛙種子

程式碼

#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define  pii pair<long long,long long >
//typedef pair<long long,long long > pii
const int maxn=3e5+5,inf=0x3f3f3f3f,mod=998244353;
const double eps=1e-6;
const ll INF=0x3f3f3f3f3f3f3f3f;
int n;
int a[maxn];
ll num[40][2];
struct trie {
    int nex[maxn*30][2], cnt;
    ll sz[maxn*30];  // 該結點結尾的字串是否存在
    void insert(int x) {  // 插入字串
        int p = 0;
        for (int i = 30; i>=0; i--) {
            int c =(x>>i)&1;
            num[i][c]+=sz[nex[p][c^1]];
            if (!nex[p][c]) nex[p][c] = ++cnt;  // 如果沒有,就新增結點
            p = nex[p][c];
            sz[p]++;
        }
    }
}t;
signed main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        t.insert(a[i]);
    }
    ll pr1=0,pr2=0;
    for(int i=30;i>=0;i--){
        if(num[i][1]<num[i][0]){
            pr1+=num[i][1];
            pr2+=(1<<i);
        }else{
            pr1+=num[i][0];
        }
    }
    printf("%lld %lld\n",pr1,pr2);
    return 0;
}

不擺爛了,寫題