codeforces-1295D(欧拉函数)
Same GCDs
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given two integers a and m. Calculate the number of integers x such that 0≤x<m and gcd(a,m)=gcd(a+x,m).
Note: gcd(a,b) is the greatest common divisor of a and b.
Input
The first line contains the single integer T (1≤T≤501≤T≤50) — the number of test cases.
Next T lines contain test cases — one per line. Each line contains two integers a and mm (1≤a<m≤10101≤a<m≤1010).
Output
Print T integers — one per test case. For each test case print the number of appropriate x-s.
Example
input
Copy
3
4 9
5 10
42 9999999967
output
Copy
6
1
9999999966
Note
In the first test case appropriate x-s are [0,1,3,4,6,7][0,1,3,4,6,7].
In the second test case the only appropriate x is 00.
题意:给定a和m,求满足gcd(a,m) = gcd(a+x,m)的x数量
题解:首先引出一个原理:gcd(a,b) = gcd(a-b,b)。由此我们可以得到当a+x>=m时,gcd(a+x,m)=gcd(a+x-m,m)。令x' = (a+x)%m,我们可以得知最多有m个不同的x',也就是说x\(\in\)[0,m-1]。问题也就转换成了gcd(a,m) = gcd(x',m)。下面我们令gcd(a,m) = y,令a = ya',m = ym',gcd(a,m) = gcd(ya',ym') = y*gcd(a',m'),可得a'与m'互质,再令x' = yx'',同上,也就是x''与m'互质,同时因为gcd(0,m') = m'>1,得出x''\(\in\)[1,m'-1],根据这个定义,我们可以明白该题的目的就是求出m'内所有与m'互质的数,即m'的欧拉函数
如何求m'的欧拉函数,\(\varphi\)(m') = m'\(\prod_{i=1}^l{(1-{1\over{p_i}})}\),m'直接利用gcd(a,m)即可求出
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<vector>
using namespace std;
using ll = long long;
const ll N = 1e6;
const double PI = acos(-1.0);
#define Test ll tesnum;tesnum = read();while(tesnum--)
ll read();
ll gcd(ll a,ll b){
if(a<b)return gcd(b,a);
if(b==0)return a;
else
return gcd(b,a%b);
}
ll phi(ll a)
{
ll rea = a;
for(ll i = 2;i*i<=a;i++){
if(a%i==0){
rea = rea-rea/i;
do a/=i;
while(a%i==0);
}
}
if(a > 1)
rea = rea-rea/a;
return rea;
}
int main()
{
Test{
ll a,m;
cin>>a>>m;
cout<<phi(m/gcd(a,m))<<endl;
};
return "BT7274", NULL;
}
inline ll read() {
ll hcy = 0, dia = 1;char boluo = getchar();
while (!isdigit(boluo)) {if (boluo == '-')dia = -1;boluo = getchar();}
while (isdigit(boluo)) {hcy = hcy * 10 + boluo - '0';boluo = getchar();}
return hcy * dia;
}