题意:
求
∑ i = 1 n ∑ j = 1 n i j gcd ( i , j ) \sum_{i=1}^{n}\sum_{j=1}^{n}ij\gcd(i,j) i=1∑nj=1∑nijgcd(i,j)
对 p p p 取模, n ≤ 1 0 10 , 5 × 1 0 8 ≤ p ≤ 1.1 × 1 0 9 n \le10^{10}, 5 ×10^8\le p \le1.1 ×10^{9} n≤1010,5×108≤p≤1.1×109
分析:
∑ i = 1 n ∑ j = 1 n i j gcd ( i , j ) \sum_{i=1}^{n}\sum_{j=1}^{n}ij\gcd(i,j) i=1∑nj=1∑nijgcd(i,j)
枚举 gcd ( i , j ) \gcd(i,j) gcd(i,j)
∑ d = 1 n d ∑ i = 1 n ∑ j = 1 n i j [ gcd ( i , j ) = d ] \sum_{d=1} ^{n} d \sum_{i=1}^{n}\sum_{j=1}^{n}ij[\gcd(i,j)=d] d=1∑ndi=1∑nj=1∑nij[gcd(i,j)=d]
利用 gcd \gcd gcd 的性质
∑ d = 1 n d ∑ i = 1 n ∑ j = 1 n i j [ gcd ( i d , j d ) = 1 ] \sum_{d=1} ^{n} d \sum_{i=1}^{n}\sum_{j=1}^{n}ij[\gcd(\frac{i}{d},\frac{j}{d})=1] d=1∑ndi=1∑nj=1∑nij[gcd(di,dj)=1]
让式子除 d 2 d^2 d2 再乘 d 2 d^2 d2
∑ d = 1 n d 3 ∑ i = 1 n ∑ j = 1 n i d ⋅ j d [ gcd ( i d , j d ) = 1 ] \sum_{d=1} ^{n} d^3 \sum_{i=1}^{n}\sum_{j=1}^{n} \frac{i}{d} \cdot \frac{j}{d}[\gcd(\frac{i}{d},\frac{j}{d})=1] d=1∑nd3i=1∑nj=1∑ndi⋅dj[gcd(di,dj)=1]
换一下上界
∑ d = 1 n d 3 ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ n d ⌋ i j [ gcd ( i , j ) = 1 ] \sum_{d=1} ^{n} d^3 \sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{n}{d} \rfloor} i j[\gcd(i,j)=1] d=1∑nd3i=1∑⌊dn⌋j=1∑⌊dn⌋ij[gcd(i,j)=1]
莫比乌斯反演
∑ d = 1 n d 3 ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ n d ⌋ i j ∑ k ∣ gcd ( i , j ) μ ( k ) \sum_{d=1} ^{n} d^3 \sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{n}{d} \rfloor} i j \sum_{k \mid \gcd(i,j)} \mu(k) d=1∑nd3i=1∑⌊dn⌋j=1∑⌊dn⌋ijk∣gcd(i,j)∑μ(k)
交换求和次序
∑ d = 1 n d 3 ∑ k = 1 ⌊ n d ⌋ μ ( k ) ∑ i = 1 ⌊ n d k ⌋ i k ∑ j = 1 ⌊ n d k ⌋ j k \sum_{d=1} ^{n} d^3 \sum_{k=1} ^{\lfloor \frac{n}{d} \rfloor} \mu(k) \sum_{i=1}^{\lfloor \frac{n}{dk} \rfloor} ik\sum_{j=1}^{\lfloor \frac{n}{dk} \rfloor} jk d=1∑nd3k=1∑⌊dn⌋μ(k)i=1∑⌊dkn⌋ikj=1∑⌊dkn⌋jk
化简后半部分
∑ d = 1 n d 3 ∑ k = 1 ⌊ n d ⌋ k 2 μ ( k ) ( ∑ i = 1 ⌊ n d k ⌋ i ) 2 \sum_{d=1} ^{n} d^3 \sum_{k=1} ^{\lfloor \frac{n}{d} \rfloor} k^2 \mu(k) (\sum_{i=1} ^{\lfloor \frac{n}{dk} \rfloor}i)^2 d=1∑nd3k=1∑⌊dn⌋k2μ(k)(i=1∑⌊dkn⌋i)2
设 T = d k T=dk T=dk
∑ T = 1 n T 2 ∑ d ∣ T d μ ( T d ) ( ∑ i = 1 ⌊ n T ⌋ i ) 2 \sum_{T=1} ^{n} T^2 \sum_{d \mid T} d\mu(\frac{T}{d}) (\sum_{i=1} ^{\lfloor \frac{n}{T} \rfloor}i)^2 T=1∑nT2d∣T∑dμ(dT)(i=1∑⌊Tn⌋i)2
因为 μ ∗ I d = φ \mu * Id=\varphi μ∗Id=φ,替换 ∑ d ∣ T d μ ( T d ) \sum \limits_{d \mid T} d\mu(\frac{T}{d}) d∣T∑dμ(dT) 得
∑ T = 1 n T 2 φ ( T ) ( ∑ i = 1 ⌊ n T ⌋ i ) 2 \sum_{T=1} ^{n} T^2 \varphi(T) (\sum_{i=1} ^{\lfloor \frac{n}{T} \rfloor}i)^2 T=1∑nT2φ(T)(i=1∑⌊Tn⌋i)2
根据 ( n 2 + n 2 ) 2 = 1 3 + 2 3 + ⋯ + n 3 (\dfrac{n^2 +n}{2})^2=1^3+2^3+\cdots+n^3 (2n2+n)2=13+23+⋯+n3
∑ T = 1 n T 2 φ ( T ) ∑ i = 1 ⌊ n T ⌋ i 3 \sum_{T=1} ^{n} T^2 \varphi(T) \sum_{i=1} ^{\lfloor \frac{n}{T} \rfloor}i^3 T=1∑nT2φ(T)i=1∑⌊Tn⌋i3
设 f ( x ) = x 2 φ ( x ) f(x)= x^2\varphi(x) f(x)=x2φ(x) 套用杜教筛, S ( n ) S(n) S(n) 为 ∑ i = 1 n f ( i ) \sum \limits_{i=1}^{n} f(i) i=1∑nf(i)
g ( 1 ) S ( n ) = ∑ i = 1 n h ( i ) − ∑ i = 1 n g ( i ) S ( ⌊ n i ⌋ ) g(1)S(n)=\sum_{i=1} ^{n}h(i)-\sum_{i=1}^{n}g(i)S(\lfloor \frac{n}{i} \rfloor) g(1)S(n)=i=1∑nh(i)−i=1∑ng(i)S(⌊in⌋)
那么 h = f ∗ g h=f *g h=f∗g,也就是 h ( n ) = ∑ d ∣ n f ( d ) g ( n d ) h(n)=\sum \limits _{d \mid n}f(d)g(\dfrac{n}{d}) h(n)=d∣n∑f(d)g(dn),带入 f ( n ) f(n) f(n) 得
h ( n ) = ∑ d ∣ n d 2 φ ( d ) g ( n d ) h(n)=\sum_{d \mid n} d^2\varphi(d)g(\frac{n}{d}) h(n)=d∣n∑d2φ(d)g(dn)
考虑把 d 2 d^2 d2 消去,所以设 g ( x ) = x 2 g(x)=x^2 g(x)=x2,故
h ( n ) = n 2 ∑ d ∣ n φ ( d ) h(n)=n^2\sum_{d \mid n}\varphi(d) h(n)=n2d∣n∑φ(d)
根据 φ ∗ I = I d \varphi *I=Id φ∗I=Id
h ( n ) = n 3 h(n)=n^3 h(n)=n3
那么 f ( x ) f(x) f(x) 的前缀和就是
S ( n ) = ( n 2 + n 2 ) 2 − ∑ i = 2 n i 2 S ( ⌊ n i ⌋ ) S(n)=(\frac{n^2+n}{2})^2-\sum_{i=2} ^{n}i^2S(\lfloor \frac{n}{i} \rfloor) S(n)=(2n2+n)2−i=2∑ni2S(⌊in⌋)
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e6 + 5;
int mod, n, euler[N], primes[N], cnt, sum[N], inv, res;
bool st[N];
unordered_map<int, int> mp;
int qmi(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void get_eulers(int n) {
euler[1] = 1;
for (int i = 2; i <= n; i ++) {
if (!st[i]) {
primes[cnt ++] = i;
euler[i] = i - 1;
}
for (int j = 0; primes[j] <= n / i; j ++) {
int t = primes[j] * i;
st[t] = 1;
if (i % primes[j] == 0) {
euler[t] = primes[j] * euler[i];
break;
}
euler[t] = (primes[j] - 1) * euler[i];
}
}
for (int i = 1; i <= n; i ++) sum[i] = (sum[i - 1] + i * i % mod * euler[i] % mod) % mod;
}
int s2(int n) {
n %= mod;
return n * (n + 1) % mod * (2 * n + 1) % mod * inv % mod;
}
int s3(int n) {
n %= mod;
return (n * (n + 1) / 2) % mod * ((n * (n + 1) / 2) % mod) % mod;
}
int Sum(int n) {
if (n < N) return sum[n];
if (mp[n]) return mp[n];
int res = s3(n);
for (int l = 2, r; l <= n; l = r + 1) {
r = n / (n / l);
res -= (s2(r) - s2(l - 1) + mod) % mod * Sum(n / l) % mod;
res = (res + mod) % mod;
}
return mp[n] = res;
}
signed main() {
cin >> mod >> n;
get_eulers(N - 1);
inv = qmi(6, mod - 2);
for (int l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
res += (Sum(r) - Sum(l - 1) + mod) % mod * s3(n / l) % mod;
res = (res % mod + mod) % mod;
}
cout << res << endl;
}