题面
给定两个数a和m,在
内寻找有多少个x使
1<=a<m<=1010
分析
询问了队友后得到了正确的建模思路。。。
可以先把问题简化,通过gcd(a,m)化简一波:
为表达简单,使
注意到此时问题变成了一个互质问题
在
内寻找有多少个x使
(x的范围可能缩小了,但是删去的部分肯定不是答案,因为那部分x包含a和m的公因子,不能使
)
联想到欧几里得算法,可以将后面的部分化到最简:当a+x大于等于m时,
分类:
a+x<m时,
,其中
a+x>=m时,
,其中
由此,问题变成求 内与m互质数的个数,即欧拉函数φ(m)
代码
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
ll gcd(ll a, ll b)
{
if (b == 0)return a;
return gcd(b, a % b);
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
ll a, m,fai=1,g;
for (int o = 0; o < t; o++)
{
cin >> a >> m;
g = gcd(a, m);
m /= g;
//求m/gcd(a,m)的欧拉函数
fai = m;
for (ll i = 2; i*i <= m; i++)
{
if (m % i == 0) {
fai = fai / i * (i - 1);
while (m % i == 0)m /= i;
}
}
if (m > 1)fai = fai / m * (m - 1);
cout << fai << endl;
}
return 0;
}