hdu 4983 欧拉函数

时间:2024-10-21 16:37:56

http://acm.hdu.edu.cn/showproblem.php?pid=4983

求有多少对元组满足题目中的公式。

对于K=1的情况,等价于gcd(A, N) * gcd(B,
N) = N,我们枚举 gcd(A, N) = g,那么gcd(B, N) = N / g。问题转化为统计满足 gcd(A, N) = g 的 A 的个数。这个答案就是 ɸ(N/g)

只要枚举 N 的 约数就可以了。答案是 Σɸ(N/g)*ɸ(g) g | N

暴力即可

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%I64d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
typedef long long LL;
const int modo = 1e9 + 7;
int k; LL euler_phi(LL n) {
LL m = sqrt(n+0.5);
LL ret = n;
for (LL i = 2; i <= m; i++) {
if (n % i == 0) {
ret = ret / i * (i-1);
while (n%i==0)
n /= i;
if(n == 1)
break;
}
} if (n > 1)
ret = ret / n * (n - 1);
return ret;
}
LL n;
int main() {
// int _;RD(_);while(_--){
// ;
// }
while(~RD2(n,k)){
if(n == 1 || k == 2)
puts("1");
else if(k > 2)
puts("0");
else{
LL ans = 0;
LL m = sqrt(n + 0.5);
for(LL i = 1;i <= m;++i){
if(n % i == 0){
ans = (ans + euler_phi(i)*euler_phi(n/i)*2) % modo;
}
}
if(m*m == n){
ans = (ans + modo - euler_phi(m)*euler_phi(m)) % modo;
}
printf("%I64d\n",ans);
}
}
return 0;
}