樱花

樱花

给定一个整数 n,求有多少正整数数对 (x,y) 满足 1x+1y=1n!

输入格式

一个整数 n

输出格式

一个整数,表示满足条件的数对数量。

答案对 109+7 取模。

数据范围

1n106

输入样例:

2

输出样例:

3

样例解释

共有三个数对 (x,y) 满足条件,分别是 (3,6),(4,4),(6,3)

 

解题思路

1x+1y=1n!x+yxy=1n!xn!+yn!=xy

  可以发现有两个自变量,因此可以通过枚举来固定x然后通过xy的关系来得到满足条件的y。其中y关于x的函数为y=xn!xn!

  现在问题就变成了有多少个正整数x使得xn!xn!是一个正整数。由于分子分母同时含有x不方便处理,因此把分子的x去掉。y=xn!xn!=(xn!+n!)n!xn!=n!+(n!)2xn!

  由于n!必然是一个正整数,因此问题又变成了有多少个正整数x使得(n!)2xn!是一个正整数。x一定正整数,但分母的xn!不一定是正整数,事实上根据1x+1y=1n!得到1y=1n!1x,由于xy均要满足正整数的条件,因此x必然要满足x>n!,因此xn!>0。因此问题就等价于有多少个正整数x使得xn!(n!)2的约数,等价于就是问(n!)2的约数个数。其中如果一个数N=P1α1P2α2Pnαn,那么约数的个数为(α1+1)(α2+1)(αn+1)

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e6 + 10, mod = 1e9 + 7;
 5 
 6 int primes[N], cnt;
 7 bool vis[N];
 8 
 9 void get_prime(int n) {
10     for (int i = 2; i <= n; i++) {
11         if (!vis[i]) primes[cnt++] = i;
12         for (int j = 0; primes[j] <= n / i; j++) {
13             vis[primes[j] * i] = true;
14             if (i % primes[j] == 0) break;
15         }
16     }
17 }
18 
19 int main() {
20     int n;
21     scanf("%d", &n);
22     get_prime(n);
23     int ret = 1;
24     for (int i = 0; i < cnt; i++) {
25         int p = primes[i], s = 0;
26         for (int j = n; j; j /= p) {
27             s += j / p;
28         }
29         ret = ret * (2ll * s + 1) % mod;
30     }
31     printf("%d", ret);
32     
33     return 0;
34 }
复制代码

 

参考资料

  AcWing 1294. 樱花(算法提高课):https://www.acwing.com/video/691/

posted @   onlyblues  阅读(146)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示