zoukankan      html  css  js  c++  java
  • 【CF888G】Xor-MST(最小生成树,Trie树)

    【CF888G】Xor-MST(最小生成树,Trie树)

    题面

    CF
    洛谷

    题解

    利用(Kruskal)或者(Prim)算法都很不好计算。
    然而我们还有一个叫啥来着?(B)啥啥的算法,就叫(B)算法吧。
    思想是对于每个点找到一条最小边,并且将这条边连上,不难证明每次至少连上了(n/2)个点。
    再将这些联通块看做一个点继续重复这个过程,时间复杂度是(log)级别的。

    我们从高位往低位看,如果我们按照(01)分类,根据上述的过程,不难得到,如果(01)两个集合都存在的话,它们之间一定会连上一条边,并且(01)分类后的两个集合一定在内部形成联通块,这就很好办了,直接分治递归处理,每次拿(Trie)算一下(01)分类后两个集合之间边的最小值然后给连上就好。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define ll long long
    #define MAX 200200
    #define pb push_back
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    int n,a[MAX],tot;
    struct Node{int ch[2];}t[MAX<<5];
    void insert(int &x,int w,int p)
    {
    	if(!x)x=++tot,t[x].ch[0]=t[x].ch[1]=0;
    	if(p==-1)return;
    	insert(t[x].ch[(w>>p)&1],w,p-1);
    }
    int Query(int x,int w,int p)
    {
    	if(p==-1)return 0;int c=(w>>p)&1;
    	if(t[x].ch[c])return Query(t[x].ch[c],w,p-1);
    	else return Query(t[x].ch[c^1],w,p-1)^(1<<p);
    }
    ll Solve(vector<int> v,int p)
    {
    	if(!v.size()||p==-1)return 0;
    	vector<int> d[2];int ret=0,rt;
    	for(int i:v)d[(i>>p)&1].pb(i);
    	if(d[0].size()&&d[1].size())
    	{
    		ret=1<<(p+1);rt=tot=0;
    		for(int i:d[0])insert(rt,i,30);
    		for(int i:d[1])ret=min(ret,Query(rt,i,30));
    	}
    	return ret+Solve(d[0],p-1)+Solve(d[1],p-1);
    }
    int main()
    {
    	n=read();vector<int> a;
    	for(int i=1;i<=n;++i)a.pb(read());
    	printf("%I64d
    ",Solve(a,30));
    	return 0;
    }
    
    
  • 相关阅读:
    bugKu getshell
    XCTF 进阶区 CAT
    php弱类型比较
    XCTF command_execution
    关于错误 openssl/ssl.h:没有那个文件或目录的解决办法
    libffi-dev : 依赖: libffi6 (= 3.2.1-4) 但是 3.2.1-4kord 正要被安装
    如何查看 Ubuntu下已安装包版本号
    git 下载指定tag版本的源码
    ubuntu 环境 openstack 源码包制成 deb 包
    fedora 国内源
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9479584.html
Copyright © 2011-2022 走看看