题目大意:
给定n-1个点,编号从2到n, a和b之间的边权值是lcm(a, b),请找出由它们组成的最小生成树。 最小生成树是一个连通的、边加权的无向图的边的子集,它将所有的顶点连接在一起,没有任何环,并且具有最小可能的边总权值。 也就是说,它是一棵边权之和尽可能小的生成树。 Lcm (a, b)是能被a和b整除的最小正整数。
不难看出除了质数以外的数均可以构建边权值为该数的值的边,而质数要构建边权值最小的边则需要与2形成边权值为2*该质数的边,所以最小生成树的边权值总和为1+2+.....+n加上3~n之间所有质数的值,此处需要用到欧拉筛。
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e7+10;
int a[maxn],prime[1000000];
bool vis[maxn];
void Prime(){
int index=0;
for(int i=2;i<=maxn;i++){
if(!vis[i]) prime[++index]=i;
for(int j=1;j<=index;j++){
if(i*prime[j]>maxn) break;
vis[i*prime[j]]=true;
if(i%prime[j]==0) break;
}
}
vis[0]=vis[1]=false;
}
signed main(){
int T;cin>>T;
Prime();
while(T--){
int n,ans=0;cin>>n;
ans+=n*(n+1)/2-3;
for(int i=2;prime[i]<=n;i++) ans+=prime[i];
cout<<ans<<endl;
}
}