hdu 6954 Minimum spanning tree(2021杭电多校1)(贪心+欧拉筛/埃氏筛)

该博客讨论了一道算法问题,题目要求找到将n-1个点连接成最小生成树的边权和,其中边权是两点标号的最小公倍数。通过分析,发现可以将所有质数连接到2上,合数连接到其因子,从而得到答案。博主提供了两种O(n)复杂度的解决方案,一种是简单的埃氏筛,另一种是优化后的埃氏筛,都能有效地解决这个问题。
摘要由CSDN通过智能技术生成

传送门
题意:给n-1个点,标号从2到n,点a和点b之间的边权为lcm(a,b),现在求将n-1个点连接起来的最小生成树的边权和
1 ≤ T ≤ 100 , 1 ≤ n ≤ 10000000 1\le T\le 100,1\le n\le 10000000 1T100,1n10000000
思路:
这个题只给了一个n,n=2只有一个点,那我们贪心地从n=3开始考虑,3肯定连接到2上,n=4时4现在连接到2上更优,n=5时5连接到2上,6的话连接到2或者3都一样
那我们现在就可以思考一下,lcm(a,b)=ab/gcd(a,b),一个数a如果是质数,它与其他比它小的任何数b的lcm都是a * b,那我们这时候把b最小化选择2就可以,如果a是合数,连接上去,我们选择a的一个因子,这样lcm就是a本身,所以最终答案就是 除2以外的质数和2+合数和
这个题n只有1e7,其实比较好做,用个欧拉筛O(n)判断质数即可

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+5;
#define ll long long
int prim[N];
int vis[N];
int cnt;
ll sum1[N];  //素数和
ll sum2[N];  //合数和 
void init(){
	vis[0]=1;
	vis[1]=1;
	for(int i=2;i<N;i++){
		if(!vis[i]) 
		{
			prim[cnt++]=i;
		}
		for(int j=0;j<cnt&&prim[j]*i<N;j++){
			vis[i*prim[j]]=1;
			if(i%prim[j]==0) break;
		}
	}
}
int main(){
	init();
	for(int i=3;i<N;i++){
		if(!vis[i]) 
		{
			sum1[i]=sum1[i-1]+i;
			sum2[i]=sum2[i-1];
		}
		else{
			sum1[i]=sum1[i-1];
			sum2[i]=sum2[i-1]+i;
		}
	}
	int t;
	scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d",&n);
		ll ans=sum1[n]*2+sum2[n];
		printf("%lld\n",ans);
	}
	return 0;
}

埃氏筛优化下复杂度近似O(n),也可以过这个题,代码稍微好写一点

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+5;
#define ll long long
int prim[N];
int vis[N];
int cnt;
ll sum1[N];  //素数和
ll sum2[N];  //合数和 
void init(){
	vis[0]=1;
	vis[1]=1;
	for(int i=2;i<N/i;i++){
		if(!vis[i]){
			for(int j=i*i;j<N;j+=i){
				vis[j]=1;
			}
		}
	}
}
int main(){
	init();
	for(int i=3;i<N;i++){
		if(!vis[i]) 
		{
			sum1[i]=sum1[i-1]+i;
			sum2[i]=sum2[i-1];
		}
		else{
			sum1[i]=sum1[i-1];
			sum2[i]=sum2[i-1]+i;
		}
	}
	int t;
	scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d",&n);
		ll ans=sum1[n]*2+sum2[n];
		printf("%lld\n",ans);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

eeemmm123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值