HDU 2588 GCD

GCD

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2437    Accepted Submission(s): 1253


Problem Description
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
 

Source
 

Recommend
lcy

题意:给两个数m,n,问能找到多少x满足(x<=m),GCD(x,m)>=n
一个一个算肯定会超时,枚举x的约数,找出x>=m的x,计算m/x的欧拉函数即可,比如x大于n,m/x的欧拉函数值为q,与p/x互质的数分别为p1,p2,p3,.....,pn,则GCD(pi*x)>=m,为什么选择pi是与p/x互质的数呢?因为这样算出来的pi*x不会和其他的数重合

#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<cmath>
#include<vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;

#define pi acos(-1.0)
#define eps 1e-10
#define pf printf
#define sf scanf
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define e tree[rt]
#define _s second
#define _f first
#define all(x) (x).begin,(x).end
#define mem(i,a) memset(i,a,sizeof i)
#define for0(i,a) for(int (i)=0;(i)<(a);(i)++)
#define for1(i,a) for(int (i)=1;(i)<=(a);(i)++)
#define mi ((l+r)>>1)
#define sqr(x) ((x)*(x))

const int inf=0x3f3f3f3f;
ll m,n,ans;
int t;

ll ouler(ll n)
{
    ll res=n;
    for(ll i=2;sqr(i)<=n;i++)
    {
        if(!(n%i))
        {
            res=res/i*(i-1);
            while(!(n%i))n/=i;
        }
    }
    if(n>1)res=res/n*(n-1);
    return res;
}

int main()
{
    sf("%d",&t);
    while(t--)
    {
        ans=0;
        sf("%I64d%I64d",&n,&m);
        for(ll i=1;sqr(i)<=n;i++)
            if(!(n%i))
            {
                if(i>=m&&sqr(i)!=n)//当i和n/i相同时只能计算一次
                    ans+=ouler(n/i);
                if(n/i>=m)
                    ans+=ouler(i);//分别计算i和n/i的欧拉函数值
            }
        pf("%I64d\n",ans);
    }
    return 0;
}






发布了73 篇原创文章 · 获赞 7 · 访问量 1万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章