cf1295D---转化,欧拉函数

题意:求有多少个x,使得对于给定的a和m,(a,m)=(a+x,m),这儿1<=a<m<10^10

答案就是m/(a,m)的欧拉函数值。首先 (a+x,m)=((a+x)%m,m)。因为若a+x>m,则(a+x,m)=(a+x-m,m)=((a+x)%m,m),而若a+x<=m显然。那么问题转化为求有多少个x'=(a+x)%m,0<=x'<m,使得(a,m)=(x',m),又由d=(a,m)=(x’,m)得(x'/d,m/d)=1,且上面每一步都可以反推(由x'/d可得x',由x'可得x),所以求m/d的欧拉函数值就行了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll a,ll b)
{
	if (b==0) return a;
	else return gcd(b,a%b);
}
int main()
{
	ll a,m,i,ans,n,t;
	cin>>t;
	while (t--)
	  {
	  	cin>>a>>m;
	  	n=m/gcd(a,m);ans=n;
	  	for (i=2;i<=int(sqrt(n));i++)
	  	  {
	  	  	if (n%i==0) ans=ans/i*(i-1); //先除以i再乘i-1,避免爆掉long long 
	  	  	while (n%i==0) n/=i;
			}
		if (n>1) ans=ans/n*(n-1);
		cout<<ans<<endl;
	  }
	return 0;
}

  

posted @ 2020-02-11 19:33  coastal_taipan  阅读(147)  评论(0编辑  收藏  举报