nyoj 1007 GCD(数学题 欧拉函数的应用)

来源:互联网 发布:网络剧发行许可证 编辑:程序博客网 时间:2024/06/05 02:40
                                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,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

#include<map>#include<set>#include<queue>#include<stack>#include<vector>#include<math.h>#include<cstdio>#include<sstream>#include<numeric>//STL数值算法头文件#include<stdlib.h>#include <ctype.h>#include<string.h>#include<iostream>#include<algorithm>#include<functional>//模板类头文件using namespace std;typedef long long ll;const int maxn=1001;const int INF=0x3f3f3f3f;const int mod=1000000007;ll Euler(ll n)//欧拉函数 求φ(n){    ll c=n,i;    for(i=2; i*i<=n; i++)    {        if(n%i==0)        {            while(n%i==0) n/=i;            c=c/i*(i-1);//φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn);        }    }    if(n!=1)        c=c/n*(n-1);    return c;}//计算满足条件 gcd(x,n)>=m的所有 x 的和ll Euler_sum(ll k){    if(k==1||k==2)        return 1;    else return k*Euler(k)/2;}int main(){    int cnt;    ll t,n,m;    scanf("%lld",&t);    while(t--)    {        ll i,sum=0;        scanf("%lld %lld",&n,&m);        for(i=1; i<=sqrt(n); i++)        {            if(n%i==0)            {                if(i>=m)//计算满足条件 >=m 的 i( i 一定是n的因子)                {                    sum=(sum+i*Euler_sum(n/i))%mod;                }                //为了防止一种特殊情况才有 i*i!=n, 比如 16 4 这一组,如果没有判断条件就会在i=4的时候计算两次                if(i*i!=n&&n/i>=m)//计算满足条件 >=m 的 n/i ( n/i 也一定是n的因子)                {                    //按步骤走这里有两种情况:(1)i和n/i都满足>=m的条件(2)i不满足>=m但是n/i满足                    //不管哪种情况如果n/i满足>=m就往下走                    sum=(sum+n/i*Euler_sum(i))%mod;                }            }        }        printf("%lld\n",sum);    }    return 0;}
原创粉丝点击