最大公约数
最大公约数
给定整数 ,求 且 为素数的数对 有多少对。
即求 , 的最大公约数。
输入格式
输入一个整数 。
输出格式
输出一个整数,表示满足条件的数对数量。
数据范围
输入样例:
4
输出样例:
4
解题思路
直接枚举是不可取的,如果定义一种映射关系,其中是质数。因此当数对的最大公约数为质数就满足这个映射关系。可以发现自变量很多,而因变量很少,因此考虑能不能来枚举因变量来求自变量的个数。
枚举种的每一个质数,如果有,那么有。记,,满足。因此问题从在中有多少个的变成了在中有多少个的,就是可见的点的模型。
因此对于质数,所要求的的个数为。因此总的答案就是。因此还需要对求一个前缀和。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 const int N = 1e7 + 10; 7 8 int primes[N], cnt; 9 bool vis[N]; 10 int phi[N]; 11 LL s[N]; 12 13 void get_prime(int n) { 14 // phi[1] = 1 // 这题中定义phi(1)=0 15 for (int i = 2; i <= n; i++) { 16 if (!vis[i]) primes[cnt++] = i, phi[i] = i - 1; 17 for (int j = 0; primes[j] <= n / i; j++) { 18 vis[primes[j] * i] = true; 19 if (i % primes[j] == 0) { 20 phi[primes[j] * i] = phi[i] * primes[j]; 21 break; 22 } 23 phi[primes[j] * i] = phi[i] * (primes[j] - 1); 24 } 25 } 26 } 27 28 int main() { 29 int n; 30 cin >> n; 31 get_prime(n); 32 for (int i = 1; i <= n; i++) { // 对phi[i]求前缀和 33 s[i] = s[i - 1] + phi[i]; 34 } 35 LL ret = 0; 36 for (int i = 0; i < cnt; i++) { 37 ret += 2 * s[n / primes[i]] + 1; 38 } 39 cout << ret; 40 41 return 0; 42 }
参考资料
AcWing 220. 最大公约数(算法提高课):https://www.acwing.com/video/695/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17063977.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效