#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int MAXN = 1000005;
const ll mod = 1e9 + 7;
ll mypow(ll a, ll b, ll mod) // a ^ b % mod
{
ll res = 1;
while (b > 0)
{
if (b & 1)
res = (res * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return res;
}
ll num[MAXN];
ll dp[MAXN];
int main()
{
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
int n, val, N;
cin >> n;
N = 0;
while (n--)
{
cin >> val;
N = max(N, val);
++num[val];
int s = sqrt(val);
for (int j = 2; j <= s; ++j)
{
if (val % j == 0)
{
++num[j];
if (j != val / j)
++num[val / j];
}
}
}
int ans = 0;
for (int i = N; i >= 2; --i)
{
dp[i] = 0;
if (num[i] == 0)
continue;
dp[i] = (ll)num[i] * mypow(2, num[i] - 1, mod) % mod;
for (int j = i + i; j <= N; j += i)
dp[i] = ((dp[i] - dp[j]) % mod + mod) % mod;
ans = (ans + dp[i] * i) % mod;
}
cout << ans << endl;
return 0;
}
题意很明显是枚举gcd
设n个数的gcd为g,则这n个数的组合方式有Cnk*g*k(k = 1 .. n)
而Cnk * k(k = 1 ... n) == 2 ^ n - 1
证明:https://www.zybang.com/question/b3f5bf8c82aad7fc37bad7aff826454e.html
3
2 4 8
其中因子2的个数有3个但有两个来自4和8,则2的组合数量要减去来自4和8的两个2所贡献的组合数量
也就是一个数n他的贡献要减去其倍数2n, 3n, kn的贡献
从后往前计算的话,但计算到n时,2n, 3n的地方都算好的