您的位置:首页 > 其它

GCD HDU - 2588(欧拉函数)

2017-09-29 23:20 489 查看
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的所有素因子以及相应的个数,然后暴力组合所有n的因子,然后和m判断大小,如果满足条件,就用欧拉函数找出个数即可,不需要任何的优化。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 200005
#define mod 1000000007
using namespace std;
int n,m;
int phi(int x)//欧拉函数
{
int ans=x;
for(int i=2;i*i<=x;i++)
{
if(x%i==0)
{
ans-=ans/i;
while(x%i==0)
x/=i;
}
if(x==1)
break;
}
if(x>1)
ans-=ans/x;
return ans;
}
int fac[20];
int e[20];
int cnt;
void getFac(int x)//晒出x的因子和相应个数
{
for(int i=2;i*i<=x;i++)
{
if(x%i==0)
{
fac[cnt]=i;
e[cnt]=0;
while(x%i==0)
{
x/=i;
e[cnt]++;
}
cnt++;
}
}
if(x>1)
{
fac[cnt]=x;
e[cnt]=1;
cnt++;
}
}
int P(int a,int b)//手写个快速幂。。。。
{
int ans=1;
while(b)
{
if(b&1)
ans*=a;
a*=a;
b>>=1;
}
return ans;
}
int ans;
void dfs(int temp,int cur)//暴力枚举因子即可
{
if(cur==cnt)
{
if(temp>=m)
ans+=phi(n/temp);
return ;
}
int now;
for(int i=0;i<=e[cur];i++)
{
now=temp*P(fac[cur],i);
dfs(now,cur+1);
}
}
int main()
{
int t;
//cout<<P(2,3);
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
if(m==1)
printf("%d\n",n);
else
{
ans=0;
cnt=0;
getFac(n);
dfs(1,0);
printf("%d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: