CF888G Xor-MST(异或生成树模板)

#include
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=2e5+10;
int a[N];
struct node{
    int cnt;
    node *nxt[2];
}*rt;
node pool[N*30];
int top;
vector<int> rf[N*30];
int lf[N*30];
void insert(int x){
    node *p=rt;
    int i;
    for(i=29;i>=0;i--){
        int sign=x>>i&1;
        if(p->nxt[sign]==NULL){
            p->nxt[sign]=pool+(++top);
            p->nxt[sign]->cnt=top;
        }
        if(sign){
            rf[p->cnt].push_back(x);
        }
        else{
            lf[p->cnt]++;
        }
        p=p->nxt[sign];
    }
}
ll ans;
ll now;
void cal(node *p,int depth,int x){
    int i;
    for(i=depth;i>=0;i--){
        int sign=x>>i&1;
        if(p->nxt[sign]){
            p=p->nxt[sign];
        }
        else{
            now+=1<<i;
            p=p->nxt[!sign];
        }
    }
}
void solve(node *p,int depth){
    int i;
    if(lf[p->cnt]&&(int)rf[p->cnt].size()!=0){
        ll mi=1e18;
        for(auto x:rf[p->cnt]){
            now=1<<depth;
            cal(p->nxt[0],depth-1,x);
            mi=min(mi,now);
        }
        ans+=mi;
    }
    if(p->nxt[0]) solve(p->nxt[0],depth-1);
    if(p->nxt[1]) solve(p->nxt[1],depth-1);
}
int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int i;
    rt=pool;
    rt->cnt=0;
    for(i=1;i<=n;i++)
        cin>>a[i];
    for(i=1;i<=n;i++)
        insert(a[i]);
    solve(rt,29);
    cout<endl;
}
View Code

 

你可能感兴趣的:(CF888G Xor-MST(异或生成树模板))