题解 P2260 [清华集训2012]模积和

题目背景

数学题,无背景。

题目描述


∑ 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=1nj=1m(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=1nj=1j≠im(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=1nj=1m(nmodi)(mmodj)i=1min(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=1n(nini)j=1m(mjmj)i=1min(n,m)(nini)(mimi)

简化一下式子,令:

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=1n(nini)

可数论分块求解。

于是:
= 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=1min(n,m)(nm+inimi2(in+im)i)
列举出自然数幂和的前两项:
∑ i = 1 n i = n ( n + 1 ) 2 \sum_{i=1}^ni=\frac{n(n+1)}{2} i=1ni=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=1ni2=6n(n+1)(2n+1)
预处理出 6 6 6的乘法逆元,再用数论分块求解就好了:

#include <cstdio>
#include <iostream>

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值