[清华集训2012]模积和

Description

Luogu2260
BZOJ2956

\[\sum_{i=1}^{n}\sum_{j=1}^{m} (n\bmod i)(m\bmod j)[i \ne j] \]

Solution

看到取模就会想整除分块的吧,那个\([i\ne j]\)其实也很好处理啊,就是最后再减去\(i=j\)的情况就行了。
我式子推的有点丑……

\[\sum_{i=1}^{n}\sum_{j=1}^{m} (n\bmod i)(m\bmod j)[i \ne j]\\ = \sum_{i=1}^{n}\sum_{j=1}^{m} (n\bmod i)(m\bmod j) - \sum_{i=1}^{\min(n, m)} (n\bmod i)(m\bmod i)\\ = \sum_{i=1}^{n}\sum_{j=1}^{m} (n - \lfloor\dfrac{n}{i}\rfloor i)(m - \lfloor\dfrac{m}{j}\rfloor j) - \sum_{i=1}^{\min(n, m)} (n - \lfloor\dfrac{n}{i}\rfloor i)(m - \lfloor\dfrac{m}{i}\rfloor i)\\ = \sum_{i=1}^{n}\sum_{j=1}^{m} (nm - m\lfloor\dfrac{n}{i}\rfloor i - n\lfloor\dfrac{m}{j}\rfloor j + \lfloor\dfrac{n}{i}\rfloor i\lfloor\dfrac{m}{j}\rfloor j) - \sum_{i=1}^{\min(n, m)}\mbox{...}\\ = n^2m^2 - m^2\sum_{i=1}^{n}\lfloor\dfrac{n}{i}\rfloor i - \mbox{...} \]

后面就是一些sb的去括号了,没啥好说的了。

Code

#include <cstdio>
#include <algorithm>

typedef long long LL;
const LL MOD = 19940417;
const LL I2 = 9970209;
const LL I6 = 3323403;

int n, m;

LL sp(LL x) {
    return x * (2 * x + 1) % MOD * (x + 1) % MOD * I6 % MOD;
}

int main() {
	scanf("%d%d", &n, &m);
	if (n < m) std::swap(n, m);
	LL ans = n % MOD * n % MOD * m % MOD * m % MOD;
	LL si = 0, sj = 0, sij = 0;
	for (int i = 1, j; i <= n; i = j+1) {
		j = n / (n / i);
		si = (si + (n / i) * (i + j) % MOD * (j - i + 1) % MOD * I2 % MOD) % MOD; 
	}
	for (int i = 1, j; i <= m; i = j+1) {
		j = m / (m / i);
		sj = (sj + (m / i) * (i + j) % MOD * (j - i + 1) % MOD * I2 % MOD) % MOD; 
	}
	ans = ((ans - m % MOD * m % MOD * si % MOD - n % MOD * n % MOD * sj % MOD) %MOD + MOD) % MOD;
	sij = si * sj % MOD;
	ans = (ans + sij) % MOD;
	ans = (ans - m % MOD * m % MOD * n % MOD + MOD) % MOD;
	si = 0;
	for (int i = 1, j; i <= m; i = j+1) {
		j = std::min(m, n / (n / i));
		si = (si + (n / i) * (i + j) % MOD * (j - i + 1) % MOD * I2 % MOD) % MOD; 
	}
	ans = (ans + m % MOD * si % MOD + n % MOD * sj % MOD) % MOD;
	sj = 0;
	for (int i = 1, j; i <= m; i = j+1) {
		j = std::min(n / (n / i) , m / (m / i));
		sj = (sj + (n / i) % MOD * (m / i) % MOD * (sp(j) - sp(i-1) + MOD) % MOD) % MOD; 
	}
	ans = (ans - sj + MOD) % MOD;
	printf("%d\n", ans);
	return 0;
}
posted @ 2018-09-29 09:58  wyxwyx  阅读(299)  评论(0编辑  收藏  举报