洛谷P2424 约数和 题解

Posted 反演的莫比乌斯环

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P2424 约数和 题解相关的知识,希望对你有一定的参考价值。

题目

约数和

题解

此题可以说完全就是一道数学题,不难看出这道题所求的是 \\(\\sum\\limits_{i=x}^{y}{\\sum\\limits_{d|i}{d}}\\) 的值。

很显然,用暴力枚举肯定会超时。所以我们采用枚举约数的方法,对于每个数 \\(d\\)\\(1\\)\\(n\\) 间满足是\\(d\\)的倍数的共有\\(\\lfloor \\frac{n}{d} \\rfloor\\)个数。所以我们构造一个函数

\\[f(n)=\\sum\\limits_{i=1}^{n}{\\sum\\limits_{d|i}}d \\]

转换后所求的值为 \\(f(y)-f(x-1)\\)

接下来我们只需专注于求 \\(f(n)\\) 即可。如加粗部分所说,不难得出 \\(f(n)\\) 可以转换为

\\[f(n)=\\sum\\limits_{d=1}^{n}{d \\cdot \\lfloor\\frac{n}{d}\\rfloor} \\]

似乎到这里直接计算已经很不错了,复杂度只有 \\(O(x+y)\\) ,然而依然会TLE。

所以我们还要想办法优化,注意到一点,对于每一个 \\(n\\) ,都有若干的 \\(d\\) 满足 \\(\\lfloor\\frac{n}{d}\\rfloor\\) 都相等。举个栗子,比如 \\(8\\) ,当 \\(d\\)\\(1\\)\\(8\\) 分别取值时, \\(\\lfloor\\frac{n}{d}\\rfloor\\) 的值分别为

\\[8,4,2,2,1,1,1,1 \\]

我们发现这里面有不少重复的数,我们则需要把这里面每个重复的数的个数算出来。

我们将 \\(d\\)\\(1\\) 开始枚举,也就是 \\(1\\) 作为左界 \\(l\\) ,那么请问右界 \\(r\\) 是什么呢?(即 \\(\\lfloor\\frac{n}{r}\\rfloor=\\lfloor\\frac{n}{l}\\rfloor\\)\\(\\lfloor\\frac{n}{r+1}\\rfloor<\\lfloor\\frac{n}{l}\\rfloor\\)

其实很简单, \\(r=\\lfloor\\frac{n}{\\lfloor n/l \\rfloor}\\rfloor\\) ,大家可以想一下是不是。然后运用等差数列求和的方式,对于每一个 \\(\\lfloor\\frac{n}{l}\\rfloor\\) 结果 \\(res\\) 都要加上

\\[\\lfloor\\frac{n}{l}\\rfloor*\\sum\\limits_{i=l}^{r}{i} =(n/l)*(r-l+1)*(l+r)/2 \\]

下一步再将 \\(l\\) 置为 \\(r+1\\) ,如此循环,直到 \\(l>n\\) 为止。

由此,这道题就愉快地解决了。

贴一下代码

代码极短,但浓缩了数学的精华。

#include<iostream>
using namespace std;
long long s(int n)
{
	if (n == 0)
		return 0;
	long long l, r;
	long long res = 0;
	for (l = 1; l <= n;l = r+1)
	{
		r = n / (n / l);
		res += (n / l) * (r - l + 1) * (l + r)/2;
	}
	return res;
}

int main()
{
	int x, y;
	cin >> x >> y;
	cout << s(y) - s(x - 1);
	return 0;
}

以上是关于洛谷P2424 约数和 题解的主要内容,如果未能解决你的问题,请参考以下文章

锣鼓 P2424 约数和

洛谷P3327 [SDOI2015]约数个数和 莫比乌斯反演

模拟(洛谷1403 [AHOI2005]约数研究)

洛谷——P1403 [AHOI2005]约数研究

洛谷 P1403 [AHOI2005]约数研究

洛谷P3327 [SDOI2015]约数个数和