• 计数题


    题目大意

    给你一个完全图,每个节点的权值为a[i],两点之间连边权值为a[i] xor b[i]求最小生成树权值及个数
    显然可以根据二进制位是0或1来分治

    解题思路

    把最高位为0和最高位为1的分治建最小生成树,再在他们之间连一条边显然是更优的。
    求最小连边可以暴力生成一棵01trie再贪心匹配
    附:当分治到全为同一数时,最小生成树个数是n的n-2次方

    #include<bits/stdc++.h>
    using namespace std;
    long long n,tot,i,j,a[100005],f[1000005],ans,sum,p,son[10000005][2];
    long long mi(long long a,long long b)
    {
    	long long v=1;
    	while(b>0)
    	{
    		if(b&1)v=(v*a)%p;
    		a=(a*a)%p;
    		b>>=1;
    	}
    	return v;
    }
    void join(long long k)
    {
    	long long now=0;
    	for(long long i=30;i>=0;i--)
    	{
    		long long t=(1<<i)&k;
    		if(t>0)t=1;
    		if(son[now][t]>0)now=son[now][t];
    		else tot++,son[now][t]=tot,now=tot,son[tot][0]=son[tot][1]=f[tot]=0;;
    	}
    	f[now]++;
    }
    long long find(long long k,long long &now)
    {
    	long long totl=0;
    	for(long long i=30;i>=0;i--)
    	{
    		long long t=(1<<i)&k;
    		if(t>0)t=1;
    		if(son[now][t]>0)now=son[now][t];
    		else totl+=(1<<i),now=son[now][t^1];
    	}
    	return totl;
    }
    long long dg(long long l,long long r,long long k)
    {
    	long long mid,i,j,z,x,y,sum,v;
    	if(l>=r)return 1;
    	if(k<0)
    	{
    		sum=mi(r-l+1,r-l-1);
    		return sum;
    	}
    	z=1<<k;mid=r+1;
    	for(i=l;i<=r;i++)
    	if((a[i]&z)>0)
    	{
    		mid=i;break;
    	}sum=1;mid--;
    	x=dg(l,mid,k-1);y=dg(mid+1,r,k-1);
    	sum=(x*y)%p;
    	if(mid!=0&&mid!=r)
    	{
    		tot=0;son[0][0]=son[0][1]=f[0]=0;
    		for(i=l;i<=mid;i++)join(a[i]);
    		x=214748364700;y=1;
    		if(tot>0)
    		for(i=mid+1;i<=r;i++)
    		{
    			v=0;
    			z=find(a[i],v);
    			if(z<x)x=z,y=f[v];
    			else if(z==x)y=(y+f[v])%p;
    		}
    		if(x!=214748364700)ans+=x;
    		sum=(sum*y)%p;
    	}
    	return sum;
    }
    int main()
    {
    	freopen("jst.in","r",stdin);
    	freopen("jst.out","w",stdout);
    	scanf("%lld",&n);p=1e9+7;
    	for(i=1;i<=n;i++)
    	{
    		scanf("%lld",&a[i]);
    	}
    	sort(a+1,a+n+1);
    	sum=dg(1,n,30);
    	printf("%lld
    %lld",ans,sum);
    }
  • 相关阅读:
    表:t_category
    使用 Javascript 代码,增加 HTML 新元素(节点)
    Kind Editor 笔记
    [ 摘 ] 对 js 运算符 “||” 和 “&&” 的总结
    Oracle 的分页查询,myBatis 配置文件
    ExtJS 的工具条及菜单
    发一个 ExtJS 4.2.0 的页面源码(规则比对公式 的设置页面)
    MyBatis 中的 set 元素用法(MyBatis 3.1.1)
    MySQL 存储过程,一个 4 层的游标,用于规则比对,不知道性能如何。
    jmeter从文件中读取参数
  • 原文地址:https://www.cnblogs.com/pzr-blog/p/13868309.html
Copyright © 2020-2023  润新知