欧拉函数 与 GCD

来源:互联网 发布:软件培训 就业 编辑:程序博客网 时间:2024/06/05 06:58

分析:假设 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
 <pre name="code" class="cpp"> #include<stdio.h>#include<math.h>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
样例输入
31 110 210000 72
样例输出
1351305000

分析:

满足条件的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<stdio.h>#include<math.h>#define ys 1000000007long 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;}        





0 0