给你一个数N,使得在1~N之间能够找到x使得x满足gcd( x , N ) >= M,
求解gcd(x,N)的和
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;
}
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;
}