做法采用一种挺巧妙的容斥求对答案贡献的思想,故发博客来记录一下
带简易注释的AC代码:
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin()+1, x.end()
using namespace std;
const int N=1e5+10;
vector<int>fac[N];
void init(int n)//求因子数
{
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j+=i)
{
fac[j].push_back(i);
}
}
}
void solve()
{
int n,ans=0;
cin>>n;
vector<int>a(n+1),g(N),f(N),num(N);
//g[x]表示值gcd(a[i],a[j])为x倍数的个数*权值
//f[x]表示值gcd(a[i],a[j])为x的个数*权值
//num[x]表示x为因子出现的次数
for(int i=1;i<=n;i++)cin>>a[i];
sort(all(a));
for(int i=1;i<n;i++)
{
for(auto j:fac[a[i]])
{
g[j]+=num[j]*(n-i);
num[j]++;
}
}
for(int i=100000;i>=1;i--)
{
f[i]=g[i];
for(int j=2*i;j<=100000;j+=i)
{
f[i]-=f[j];//f[i]=g[i]-f[2*i]-f[3*i]...f[k*i]
}
ans+=f[i]*i;
}
cout<<ans<<endl;
}
signed main()
{
//cout<<setiosflags(ios::fixed);
//cout.precision(2);
init(100000);
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
cin>>t;
while(t--)
{
solve();
}
return 0;
}