[CF888G]Xor-MST

Posted fyh-ssgss

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF888G]Xor-MST相关的知识,希望对你有一定的参考价值。

G - Xor-MST

题解

最小异或生成树
先把所有二进制数上Trie树,然后为了使得异或最小,根据异或的性质,trie树的左右子树都应该自己先连成一个连通块,然后在两个连通块内找到两个数使得异或值最小,这样就能进行连通了。
左右子树的话递归下去处理,在计算两个子树上异或值最小的时候用启发式合并,枚举大小较小的那棵子树的数值,在另外一棵子树上跑。
复杂度(O(nloglogn))
为什么我维护了Trie树的那么多信息??

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
const int maxn=200010;
int n,v[maxn],ch[32*maxn][2],size[32*maxn],sz,val[maxn*32],L[maxn*32],R[maxn*32],dfn[32*maxn],deep[32*maxn],dfs_clock=1;
void insert(int x)
{
    int now=0;
    for(int i=31;i>=0;i--)
    {
        int c=(x>>i)&1;
        if(!ch[now][c])ch[now][c]=++sz;
        now=ch[now][c];
    }
    val[now]=x;
} 
void dfs(int now)
{
    L[now]=dfs_clock;
    if(val[now])dfn[dfs_clock++]=val[now],size[now]=1;
    for(int i=0;i<2;i++)
        if(ch[now][i])
        {
            deep[ch[now][i]]=deep[now]-1;
            dfs(ch[now][i]);
            size[now]+=size[ch[now][i]];
        }
    R[now]=dfs_clock;
}
int query(int x,int u)
{
    x&=((1<<deep[u])-1);
    int now=u;
    for(int i=deep[u]-1;i>=0;i--)
    {
        int c=(x>>i)&1;
        if(!ch[now][c])c^=1;
        now=ch[now][c];
    }
    return val[now];
}    
LL calc(int u)
{
    if(!ch[u][0] && !ch[u][1])return 0;
    if(!ch[u][0])return calc(ch[u][1]);
    if(!ch[u][1])return calc(ch[u][0]);
    int x=ch[u][0],y=ch[u][1],ans=2147483647;
    if(size[x]>size[y])swap(x,y);
    for(int i=L[x];i<R[x];i++)ans=min(ans,query(dfn[i],y)^dfn[i]);
    return calc(ch[u][0])+calc(ch[u][1])+ans;
}
int main()
{
    n=read();
    for(int i=0;i<n;i++)v[i]=read();
    sort(v,v+n);
    n=unique(v,v+n)-v;
    for(int i=0;i<n;i++)insert(v[i]);
    deep[0]=32;dfs(0); 
    printf("%lld
",calc(0));
    return 0;
}

以上是关于[CF888G]Xor-MST的主要内容,如果未能解决你的问题,请参考以下文章

CF888G Xor-MST

[CF888G]Xor-MST

Codeforces 888G Xor-MST - 分治 - 贪心 - Trie

CodeForces - 888G Xor-MST(贪心+字典树+最小生成树)

CF888GXor-MST Trie树(模拟最小生成树)

$CF888G Xor-MST$ 最小生成树