分析:假设
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 样例输入
-
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<stdio.h>
#include<math.h>
#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;
}