数学题,无背景。
求
∑ i = 1 n ∑ j = 1 m ( n m o d    i ) ( m m o d    j ) , i = ̸ j \sum_{i=1}^n\sum_{j=1}^m(n\mod i)(m\mod j),i=\not j i=1∑nj=1∑m(nmodi)(mmodj),i≠j
mod 19940417 的值
两个整数n m
答案 mod 19940417
听机房dalao说好像叫快速荷叶叶变换。
推推式子吧:
ans = ∑ i = 1 n ∑ j = 1 ∧ j = ̸ i m ( n m o d    i ) ( m m o d    j ) \text{ans}=\sum_{i=1}^n\sum_{j=1∧j=\not i}^m(n\mod i)(m\mod j) ans=i=1∑nj=1∧j≠i∑m(nmodi)(mmodj)
根据容斥原理,拆分成两个式子:
= ∑ i = 1 n ∑ j = 1 m ( n m o d    i ) ( m m o d    j ) − ∑ i = 1 min ( n , m ) ( n m o d    i ) + ( m m o d    i ) =\sum_{i=1}^{n}\sum_{j=1}^m(n\mod i)(m\mod j)-\sum_{i=1}^{\min(n,m)}(n\mod i)+(m\mod i) =i=1∑nj=1∑m(nmodi)(mmodj)−i=1∑min(n,m)(nmodi)+(mmodi)
根据取余的定义,我们有:
= ∑ i = 1 n ( n − ⌊ n i ⌋ i ) ∑ j = 1 m ( m − ⌊ m j ⌋ j ) − ∑ i = 1 min ( n , m ) ( n − ⌊ n i ⌋ i ) ( m ⌊ m i ⌋ i ) =\sum_{i=1}^{n}(n-\lfloor\frac{n}{i}\rfloor i\big)\sum_{j=1}^m(m-\lfloor\frac{m}{j}\rfloor j\big)-\sum_{i=1}^{\min(n,m)}(n-\lfloor\frac{n}{i}\rfloor i)(m\lfloor\frac{m}{i}\rfloor i) =i=1∑n(n−⌊in⌋i)j=1∑m(m−⌊jm⌋j)−i=1∑min(n,m)(n−⌊in⌋i)(m⌊im⌋i)
简化一下式子,令:
L ( n ) = ∑ i = 1 n ( n − ⌊ n i ⌋ i ) L(n)=\sum_{i=1}^n\big(n-\left\lfloor\frac{n}{i}\right\rfloor i\big) L(n)=i=1∑n(n−⌊in⌋i)
可数论分块求解。
于是:
= L ( n ) L ( m ) − ∑ i = 1 min ( n , m ) ( n m + ⌊ n i ⌋ ⌊ m i ⌋ i 2 − ( ⌊ n i ⌋ + ⌊ m i ⌋ ) i ) =L(n)L(m)-\sum_{i=1}^{\min(n,m)}\bigg(nm+\left\lfloor\frac{n}{i}\right\rfloor\left\lfloor\frac{m}{i}\right\rfloor i^2-(\left\lfloor\frac{n}{i}\right\rfloor+\left\lfloor\frac{m}{i}\right\rfloor)i\bigg) =L(n)L(m)−i=1∑min(n,m)(nm+⌊in⌋⌊im⌋i2−(⌊in⌋+⌊im⌋)i)
列举出自然数幂和的前两项:
∑ i = 1 n i = n ( n + 1 ) 2 \sum_{i=1}^ni=\frac{n(n+1)}{2} i=1∑ni=2n(n+1)
∑ i = 1 n i 2 = n ( n + 1 ) ( 2 n + 1 ) 6 \sum_{i=1}^ni^2=\frac{n(n+1)(2n+1)}{6} i=1∑ni2=6n(n+1)(2n+1)
预处理出 6 6 6的乘法逆元,再用数论分块求解就好了:
#include
#include
using namespace std;
typedef long long ll;
const ll M = 19940417;
const ll P = 3323403;
ll n, m, ans;
inline ll sum(ll l, ll r) { return (l + r) * (r - l + 1) / 2 % M; }
inline ll qsum(ll n) { return (n * (n + 1)) % M * (2 * n + 1) % M * P % M; }
ll L(ll n) {
ll res = 0;
for(ll l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
res = (res + n * (r - l + 1) % M - sum(l, r) * (n / l) % M + M) % M;
}
return res;
}
ll cal(ll n, ll m) {
ans = L(n) * L(m) % M;
for(ll l = 1, r, t1, t2, t3; l <= min(n, m); l = r + 1) {
r = min(n / (n / l), m / (m / l));
t1 = (n * m % M * (r - l + 1)) % M;
t2 = (n / l) * (m / l) % M * (qsum(r) - qsum(l - 1) + M) % M;
t3 = (n / l * m % M + m / l * n % M) * sum(l, r) % M;
ans = (ans - (t1 + t2 - t3 + M) % M + M) % M;
}
return ans;
}
int main()
{
scanf("%lld %lld", &n, &m);
printf("%lld", cal(n, m) % M);
return 0;
}