链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
牛牛在做一道数学题,他发现自己不怎么会做,请你帮帮他
求有多少a,b,c,d满足ab = cd, 1<=a,b,c,d<=n, 模 109+7
输入描述:
输入一个整数n (1 ≤ n ≤ 109)
输出描述:
输出一个整数
备注:
子任务一30分:n<=10000 子任务二30分:n<=1000000 子任务三40分:n<=1000000000
解题思路
题意就是求有多少组a,b,c,d,使得 。
首先,a可以分解为 ,c可以分解为
,
就是 k1*b=k2*d。
接下来进行分类讨论:
1、k1=k2时,也就是a=c,这时候需要注意a=c=1时,1的任意次方都等于1;
1.1 时,b和d都有n种选择,ans=n*n;
1.2 时,
需要 b=d,a和c有n-1种选择,b和d有n种选择,ans=(n-1)*n
2、k1>k2时,k1此时>=2;此时p的范围: , 然后去遍历k1和k2,要求gcd(k1,k2)=1。因为
的情况在gcd(k1,k2)=1时候已经出现过了。比如p=2,k1=4,k2=6,此时a=16,c=64,b和d的可能选择有(2,3)、(4,6)……这种情况在p=4,k1=2,k2=3,这种情况的时候已经计算过了,因此我们只需要考虑gcd(k1,k2)=1的情况。
k1*b=k2*d 的b和d取法有n/k1种:
举个例子:n=16,k1=3,k2=2时;
k1 | * | b | = | k2 | * | d |
3 | * | 2 | = | 2 | * | 3 |
3 | * | 4 | = | 2 | * | 6 |
3 | * | 8 | = | 2 | * | 9 |
3 | * | 10 | = | 2 | * | 12 |
3 | * | 12 | = | 2 | * | 15 |
b和d的取法有5种,5=16/3;
这种情况ans=n/k1;
3、k1<k2时,和k1>k2是对称的,答案和情况2相同。
代码如下
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll gcd(ll x,ll y)
{
return y?gcd(y,x%y):x;
}
int main()
{
ll n,a,b,c,d,k1,k2,ans;
cin>>n;
ans=n*n%mod;
ans=ans+n*(n-1)%mod;
ll p,sqn=sqrt(n);
for(p=2;p<=sqn;p++)
{
for(k1=1,a=p;a<=n;a*=p,k1++)
{
for(k2=1;k2<k1;k2++)
{
if(gcd(k1,k2)==1)
{
ans=(ans+n/k1*2)%mod;
}
}
}
}
cout<<ans;
return 0;
}