GCD
The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the largest divisor common to a and b,For example,(1,2)=1,(12,18)=6.
(a,b) can be easily found by the Euclidean algorithm. Now Carp is considering a little more difficult problem:
Given integers N and M, how many integer X satisfies 1<=X<=N and (X,N)>=M.
Input
The first line of input is an integer T(T<=100) representing the number of test cases. The following T lines each contains two numbers N and M (2<=N<=1000000000, 1<=M<=N), representing a test case.
Output
For each test case,output the answer on a single line.
Sample Input
3
1 1
10 2
10000 72
Sample Output
1
6
260
题意:输入 N 和 M (2<=N<=1000000000, 1<=M<=N), 找出所有满足1<=X<=N 且 gcd(X,N)>=M 的 X 的数量.
思路:看见 gcd(X,N) >= M 很容易想到枚举 N 的大于 M 的因子。
一开始我在想,假设 X 是 N 中一个 >= M 的因子,那么 ans 直接 += N / X,也就是 X , 2 * X, .... N / X * X 与 N 的gcd肯定也 >= M,然后找到所有 >= M 的因子即可。但是你会发现,这样算是会有重复的。
比如 N = 12, M = 2,其中 3 倍的4 == 4 倍的3 ..
所以对于因子 X,ans 应该 += phi(N / X),这样也就相当于枚举所有可能的 gcdX(即 X),然后计算 gcd(y * X, N) == X 的 y 的个数(即 phi(N / X)),求和。
为什么是 ans += phi(N / X)? 假设数 A = p * d,B = q * d,那么 gcd(A,B) == d,且 p 一定与 q 互质,假如现在要找 gcd(A,C) == d,那么 C / d 一定与 p 互质,也就是 phi(p)
AC代码:
#include<bits/stdc++.h>
#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl
#define pii pair<int,int>
#define clr(a,b) memset((a),b,sizeof(a))
#define rep(i,a,b) for(int i = a;i < b;i ++)
#define pb push_back
#define MP make_pair
#define LL long long
#define ull unsigned LL
#define ls i << 1
#define rs (i << 1) + 1
#define INT(t) int t; scanf("%d",&t)
using namespace std;
const int maxn = 2e5 + 10;
int phi[maxn];
int euler(int n){
int ans = n;
for(int i = 2;i * i <= n;++ i){
if(n % i == 0){
ans = ans / i * (i - 1);
while(n % i == 0)
n /= i;
}
}
if(n > 1) ans = ans / n * (n - 1);
return ans;
}
int main() {
int t; scanf("%d",&t);
while(t --){
int n,m; scanf("%d%d",&n,&m);
set<int> factor; factor.clear();
for(int i = 1;i * i <= n;++ i){
if(n % i == 0){
if(i >= m)
factor.insert(n / i);
if(n / i >= m)
factor.insert(i);
}
}
int ans = 0;
for(auto it : factor)
ans += euler(it);
cout << ans << endl;
}
return 0;
}