其他分享
首页 > 其他分享> > P1445 [Violet]樱花 一点点数论

P1445 [Violet]樱花 一点点数论

作者:互联网

P1445 [Violet]樱花

​ 九月十五号考试T4。

题目链接

​ 一点点数论吧。(就是没想出来)

\[\frac{1}{x} + \frac{1}{y} = \frac{1}{n!} \\ xy = xn! + yn! \\ n!^2 - xn! - yn! + xy = n!^2 \\ (x - n!)(y - n!)=n!^2 \\ ab = n!^2 \]

​ 因为唯一分解定理:\(n! = p_1^{r_1}p_2^{r_2}...p_n^{r_n}\);

​ 所以:\(ab = n!^2 = p_1^{2r_1}p_2^{2r_2}...p_n^{2r_n}\);

​ 每一组合法的\(x,y\),对应一组整数\(a, b\),所以我们所求的答案就是\(a\)的个数。显然,\(a\)为\(n!\)的因子,那么\(a\)的个数就是:\((2r_1 + 1)(2r_2 + 2)...(2r_n + 1)\)。

#include <bits/stdc++.h>

#define int long long 

using namespace std;

const long long mod = 1e9 + 7, N = 1e6 + 5;
int n, cnt, ans, num[N], prime[N];
bool is_prime[N];

void make_prime() {
	for(int i = 2;i <= N - 5; i++) {
		if(!is_prime[i])  prime[++cnt] = i;
		for(int j = 1;j <= cnt && i * prime[j] <= N - 5; j++) {
			is_prime[i * prime[j]] = 1;
			if(!(i % prime[j])) break;
		}
	}
}

void work() {
	for(int i = 1;prime[i] <= n && i <= cnt; i++) {
		for(int j = prime[i];j <= n; j *= prime[i]) num[i] += (n / j);
        num[i] %= mod;
    }
}

signed main() {
	
	// freopen("chino.in","r",stdin); freopen("chino.out","w",stdout);
	
	make_prime();

	cin >> n; ans = 1;

	work();

	for(int i = 1;i <= cnt; i++) 
        if(num[i]) 
            ans = 1ll * ans * (1ll * num[i] * 2 % mod + 1) % mod;
	
	printf("%lld", ans);
	
	fclose(stdin); fclose(stdout);
	return 0;
}

标签:樱花,prime,P1445,frac,2r,...,int,long,Violet
来源: https://www.cnblogs.com/czhui666/p/13683036.html