非常著名的一道经典题。
考虑一个性质:如果两个点GCD相同必然更优。
于是我们有了一些点权互不相同的点。
发现点权并不大,从大到小枚举点权。
用并查集维护联通性。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
inline void read(int &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
const int N=1e6+10;
int T[N];
int fa[N];
inline int getfa(int x){
if(fa[x]==x)return x;
else return fa[x]=getfa(fa[x]);
}
int n;
int val[N];
int Mx;
int ans=0;
int main(){
read(n);
for(int i=1;i<=n;++i){
read(val[i]);
Mx=max(Mx,val[i]);
if(T[val[i]])ans+=val[i];
else T[val[i]]=fa[i]=i;
}
for(int i=Mx;i>=1;--i){
int now=0;
for(int j=1;j*i<=Mx;++j){
if(T[i*j]){
if(!now)now=T[i*j];
else{
if(getfa(now)==getfa(T[i*j]))continue;
else{
fa[getfa(now)]=getfa(T[i*j]);
ans+=i;
}
}
}
}
}
cout<<ans;
}