BZOJ2721或洛谷1445 [Violet]樱花

BZOJ原题链接

洛谷原题链接

其实推导很简单,只不过我太菜了想不到。。。又双叒叕去看题解
简单写下推导过程。
原方程:$$dfrac{1}{x} + dfrac{1}{y} = dfrac{1}{n!}$$
通分:$$dfrac{x + y}{xy} = dfrac{1}{n!}$$
十字相乘:$$(x + y) imes n! = xy$$
((x + y) imes n!)移到右项:$$xy - (x + y) imes n! = 0$$
两边同时加上((n!)^2):$$(n!)^2 - (x + y) imes n! + xy = (n!) ^ 2$$
左项因式分解:$$(x - n!) imes (y - n!) = (n!) ^ 2$$
(a = x - n!, b = y - n!),则方程变为:$$ab = (n!) ^ 2$$
显然确定(a)就能确定(b),也能确定(x, y),所以(a)有几组解即是原方程(x, y)解的组数。
而根据算术基本定理,(n! = prod limits _{i = 1} ^ k p_i ^ {c_i}),所以((n!) ^ 2 = prod limits _{i = 1} ^ k p_i ^ {2c_i})
再根据约数个数定理,((n!) ^ 2)的约数个数即是(prod limits _{i = 1} ^ k (2c_i + 1)),这就是答案

#include<cstdio>
using namespace std;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
int pr[N];
bool v[N];
inline int re()
{
	int x = 0;
	char c = getchar();
	bool p = 0;
	for (; c < '0' || c > '9'; c = getchar())
		p |= c == '-';
	for (; c >= '0' && c <= '9'; c = getchar())
		x = x * 10 + c - '0';
	return p ? -x : x;
}
int main()
{
	int i, s = 1, c, n, l = 0;
	long long j;
	n = re();
	v[0] = v[1] = 1;
	for (i = 1; i <= n; i++)
	{
		if (!v[i])
			pr[++l] = i;
		for (j = 1; j <= l; j++)
		{
			if (i * pr[j] > n)
				break;
			v[i * pr[j]] = 1;
			if (!(i % pr[j]))
				break;
		}
	}
	for (i = 1; i <= l; i++)
	{
		c = 0;
		for (j = pr[i]; j <= n; j *= pr[i])
			c = (1LL * c + n / j) % mod;
		s = 1LL * s * (c << 1 | 1) % mod;
	}
	printf("%d", s);
	return 0;
}
原文地址:https://www.cnblogs.com/Iowa-Battleship/p/9890221.html