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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章