AcWing 220. 最大公约数 | 欧拉函数
Posted l999q
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 220. 最大公约数 | 欧拉函数相关的知识,希望对你有一定的参考价值。
题目描述
给定整数N,求1<=x,y<=N且GCD(x,y)为素数的数对(x,y)有多少对。
GCD(x,y)即求x,y的最大公约数。
输入格式
输入一个整数N
输出格式
输出一个整数,表示满足条件的数对数量。
数据范围
1≤N≤10^7
输入样例:
4
输出样例:
4
题解:本题要求1<=x,y<=N且GCD(x,y)为素数的数对(x,y)数量,相当于求:对于N以内的每一个素数p,1<=x,y<=N/p 中GCD(x,y)为1的数对(x,y)数量和。我们知道欧拉函数的定义是1~n中与n互质的数的个数,那么对于p,1<=x,y<=N/p 中GCD(x,y)为1的数对(x,y)数量为φ(1)+φ(2)...+φ(N/p),可以用前缀和计算。要注意:x,y大小关系无影响所以要*2,但x,y相同时只算一次所以要-1。题目就变成了求\[\sum_p是素数^p≤n 2*\sum_i=1^n/pφ(i) -1\] 也可以用\[\sum_p是素数^p≤n 2*\sum_i=2^n/pφ(i) +1\]。
代码:
#include <bits/stdc++.h> using namespace std; #define ll long long const int N = 1e7 + 10; int v[N],prime[N]; ll sum[N],phi[N]; int cnt = 0; int main() int n; scanf("%d",&n); phi[1]=1; for (int i = 2; i <= n; i++) if(!v[i]) v[i] = i;prime[cnt++] = i; phi[i] = i-1; for (int j = 0; j < cnt; j++) if (prime[j] > v[i] || prime[j] > n/i) break; v[i*prime[j]] = prime[j]; phi[i*prime[j]] = phi[i] * (i%prime[j]?prime[j]-1:prime[j]); for (int i = 1; i <= n; i++) sum[i] = sum[i-1]+phi[i]; ll ans = 0; for (int i = 0; i < cnt; i++) int num = n/prime[i]; ans += 2*sum[num]-1; printf("%lld\n",ans); return 0;
以上是关于AcWing 220. 最大公约数 | 欧拉函数的主要内容,如果未能解决你的问题,请参考以下文章