HDU - 2588 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,求满足gcd(x, n)>=m 且1<=x<=n的x的个数

思路设有一个k满足 gcd(x, n) = k (k>=m) 那么x和n一定是k的倍数

如果 x = a * k , n= b * k,那么有a<=b且a, b 互质(如果不互质的话,x和n的最小公倍数就比k要大了)

那么问题就转化成,枚举k,如果它满足条件(>=m并且是n的因数),那么求小于等于b的,且与b互质的数有几个(b=n/k),然后进行累加,就是答案了。

求与一个数互质的数有几个,,就用欧拉函数就可以。枚举k的话,我们还要用到一点小技巧,我们只枚举到sqrt(n) 就可以了,因为如果i是n的因数,那么n/i也是n的因数,只要他们其中一个>=m,我们就对另一个求欧拉函数,然后累加到答案里。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int get_phi(int n)
{
    int res=n;
    for(int i=2;i<=n/i;i++)
    {
        if(n%i==0)
        {
            res=res/i*(i-1);
            while(n%i==0) n/=i;
        }
    }
    if(n>1)
        res=res/n*(n-1);
    return res;
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,m,ans=0;
		cin>>n>>m;
		for(int i=1;i<=n/i;i++)
		{
			if(n%i==0)
			{
				if(i>=m)
					ans+=get_phi(n/i);
				if(n/i>=m && i!=n/i)
					ans+=get_phi(i);
			}
		}
		cout<<ans<<endl;
	}
	return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值