GCD
时间限制:1000 ms | 内存限制:65535 KB
难度:3
输入
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
上传者
描述
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.
思路:
要求gcd(x,n)>=m,可以枚举gcd(x,n),然后乘以一个倍数,就可以得到x,并且这个倍数必须与n互质。
我们要求所有x的和,就可以利用欧拉函数,求出来与n互质的所有数之和,再乘以gcd(x,n),就可以得出在gcd(x,n)下,所有x的和。
euler_sum函数直接照搬大佬的模板。
代码:
#include<bits/stdc++.h>
using namespace std;
#define MAXN 2005
#define ll long long
#define inf 0x3f3f3f3f
#define mod 1000000007
ll n,m;
int euler(int n){ //返回euler(n)
int res=n,a=n;
for(int i=2;i*i<=a;i++){
if(a%i==0){
res=res/i*(i-1);//先进行除法是为了防止中间数据的溢出
while(a%i==0) a/=i;
}
}
if(a>1) res=res/a*(a-1);
return res;
}
ll euler_sum(ll n)
{
if(n==1 || n==2) return 1;
return n*euler(n)/2;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&n,&m);
ll ans=0;
for(ll i=1;i*i<=n;i++)
{
if(n%i==0)
{
if(i>=m) ans=(ans+i*euler_sum(n/i))%mod;
if(n/i>=m && i!=n/i) ans=(ans+(n/i)*euler_sum(i))%mod;
}
}
printf("%lld\n",ans);
}
return 0;
}
/*
*/