欧拉函数 与 GCD

分析:假设  gcd(X,N) =d, 令 N = p * d,X = q * d,一定有 p,q 互质,又因为 X <= N,所以q <= p,即 q 的个数正好对应p的欧拉函数,q 的个数即为x的个数 ,即gcd(X,N) = d 的X的个数是N/d 的欧拉函数值。

Sum

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述

            给你一个数N,使得在1~N之间能够找到x使得x满足gcd( x ,  N  ) >= M,

求解gcd(x,N)的和

输入
多组测试数据

每行输出两个数N,M(N,M不超int)
输出
输出sum
样例输入
5 3
样例输出
5
 
 
#include
#include
long long  oular(long long n)
{
    int m=(int)sqrt(n+0.5);
    long long ans=n;
    for(long long i=2;i<=m;i++)
        if(n%i==0)
        {
            ans=ans/i*(i-1);//欧拉函数
            while(n%i==0)
                n/=i;
        }
    if(n>1)
        ans=ans/n*(n-1);
    return ans;
}
int main()
{
    int t;
    long long n,m,ans;
    while(~scanf("%lld%lld",&n,&m))
    {
        ans=0;
        long long tem=(long long)sqrt(n+0.5);
        for(long long i=1;i<=tem;i++)//枚举最大公约数
        {
            if(n%i==0)
            {
                if(i>=m)
                    ans+=oular(n/i)*i;//求出满足题意的个数 再乘以对应的最大公约数就是 所要求的结果
                if(i*i!=n&&n/i>=m)
                    ans+=oular(i)*(n/i);
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}        


 
  

GCD

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述
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,please answer sum of  X satisfies 1<=X<=N and (X,N)>=M.
输入
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 (1<=N<=10^9, 1<=M<=10^9), representing a test case.
输出
Output the answer mod 1000000007
样例输入
3
1 1
10 2
10000 72
样例输出
1
35
1305000

分析:

满足条件的X个数有euler(N/d)个,所以只需要求出不超过N/d且与N/d互素的那些数的和,然後乘以d就是最大公约数为d时 对应的部分結果。而不超过N/d且与N/d互素的那些数的和为   N/d * euler(N/d) / 2,注意当N/d = 1时,結果是1而不是0。

 
#include
#include
#define ys 1000000007
long long  oular(long long n)
{
    int m=(int)sqrt(n+0.5);
    long long ans=n;
    for(long long i=2;i<=m;i++)
        if(n%i==0)
        {
            ans=ans/i*(i-1);
            while(n%i==0)
                n/=i;
        }
    if(n>1)
        ans=ans/n*(n-1);
    return ans;
}
long long sum_oular(long long n)//不超过 N/d 且与 N/d互素的那些数的和
{
    if(n==1) return 1;
        return n*oular(n)/2;
}
int main()
{
    int t;
    long long n,m,ans;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld%lld",&n,&m);
        ans=0;
        long long tem=(long long)sqrt(n+0.5);
        for(long long i=1;i<=tem;i++)
        {
            if(n%i==0)
            {
                if(i>=m)
                    ans=(ans+sum_oular(n/i)*i)%ys;
                if(i*i!=n&&n/i>=m)
                    ans=(ans+sum_oular(i)*(n/i))%ys;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}
        





你可能感兴趣的:(数论)