Problem

求解$\sum ^{n}{i=1}\sum ^{i}{j=1}\gcd ( i^{a}-j^{a} , i^b-j^b)[\gcd(i,j)=1][\gcd(a,b)=1]$

$1 \le n \le 10^9$

Solution

因为$\gcd(i,j)=1$

原式等价于$\sum ^{n}{i=1}\sum ^{i}{j=1}i^{\gcd (a,b)}-j^{\gcd (a,b)}[\gcd(i,j)=1][\gcd(a,b)=1]$

又$\gcd(a,b)=1$

式子化简为$\sum ^{n}{i=1}\sum ^{i}{j=1}i-j[\gcd(i,j)=1]$

对称变换得$(\sum ^{n}{i=1}\sum ^{i}{j=1}j[\gcd(i,j)=1])-1$

$\sum^n_{i=1}i[\gcd(i,n)=1]=\frac{n\ast\varphi(n)+[n=1]}{2}$

所以原式等价于$\frac{(\sum^{n}_{i=1}i\ast\varphi(i))-1}{2}$

记$S(n)=\sum^{n}_{i=1}i\ast\varphi(i),f(n)=n\ast\varphi(n)$

考虑到狄利克雷卷积$(\varphi \ast I)(n) = id$

我们对$f$卷上单位函数$id$来消除系数

$(f \ast id)(n)=\sum_{d|n}f(d) \ast \frac{n}{d}=\sum_{d|n}d \ast \varphi(d) \ast \frac{n}{d}=n \ast \sum_{d|n}\varphi(d)=n^2$

$\sum_{i=1}^ni^2=\sum_{i=1}^n\sum_{d|i}d \ast \varphi(d)\ast \dfrac{i}{d}$

枚举约数转枚举倍数有 $\sum_{d=1}^n\sum_{d|i}\frac{i}{d}\ast \varphi(\frac{i}{d}) \ast d$

提取$d$之后发现我们可以得到原函数

$\sum_{d=1}^nd\sum_{d|i}\dfrac{i}{d} \ast \varphi(\frac{i}{d})=\sum_{d=1}^ndS(\lfloor \dfrac{n}{d} \rfloor)$

则有$S(n)=\sum_{i=1}^ni^2-\sum_{i=2}^niS(\lfloor \frac{n}{i} \rfloor)$

预处理$S$的$n^{\frac{2}{3}}$项,递归数值分块计算即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <bits/stdc++.h>
typedef long long ll;
const int MOD = 1e9 + 7, N = 2e6 + 5;
bool notp[N];
int prime[N], pnum;
ll phi[N];
void sieve() {
memset(notp, 0, sizeof(notp));
notp[0] = notp[1] = phi[1] = 1;
pnum = 0;
for (int i = 2; i < N; i++) {
if (!notp[i]) {
prime[++pnum] = i;
phi[i] = i - 1;
}
for (int j = 1; j <= pnum && prime[j] * i < N; j++) {
notp[prime[j] * i] = 1;
if (i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
}
ll inv(ll a, ll m) {
if (a == 1) return 1;
return inv(m % a, m) * (m - m / a) % m;
}
ll inv6, inv2;
void init() {
sieve();
for (int i = 1; i < N; i++) phi[i] = (1ll * phi[i] * i + phi[i - 1]) % MOD;
}
ll mp[2][N], n;
ll f(ll x) { return (1ll * x * (x + 1) / 2) % MOD; }
std::unordered_map<ll, ll> hs;
ll S(ll n) {
if (n < N) return phi[n];
if (hs[n]) return hs[n];
ll res = (n % MOD) * ((n + 1) % MOD) % MOD * ((2 * n + 1) % MOD) % MOD *
inv6 % MOD;
for (ll i = 2, last; i <= n; i = last + 1) {
last = n / (n / i);
res += MOD - (f(last) - f(i - 1) + MOD) % MOD * S(n / i) % MOD;
res %= MOD;
}
return hs[n] = res;
}
int T;
int main() {
scanf("%d", &T);
memset(mp, -1, sizeof(mp));
init();
inv6 = inv(6, MOD);
inv2 = inv(2, MOD);
while (T--) {
int a, b;
scanf("%lld%d%d", &n, &a, &b);
printf("%lld\n", (S(n) - 1 + MOD) % MOD * inv2 % MOD);
}
return 0;
}