樱花(约数之和)

题目描述

给定一个整数 n,求有多少正整数数对 (x,y) 满足 1/x+1/y=1/n!。

输入格式

一个整数 n。

输出格式

一个整数,表示满足条件的数对数量。
答案对 109+7 取模。

数据范围

1≤n≤106

输入样例
2
输出样例
3

样例解释

共有三个数对 (x,y) 满足条件,分别是 (3,6),(4,4),(6,3)。

题目分析

首 先 我 们 先 对 公 式 进 行 一 下 化 简 : 首先我们先对公式进行一下化简:
1 / x + 1 / y = 1 / n ! 1/x+1/y=1/n! 1/x+1/y=1/n!
( x + y ) / ( x ∗ y ) = 1 / n ! (x+y)/(x*y)=1/n! (x+y)/(xy)=1/n!
( x + y ) ∗ n ! = x ∗ y (x+y)*n!=x*y (x+y)n!=xy
x ∗ n ! = y ( x − n ! ) x*n!=y(x-n!) xn!=y(xn!)
y = ( x ∗ n ! ) / ( x − n ! ) y=(x*n!)/(x-n!) y=(xn!)/(xn!)
y = ( x − n ! + n ! ) ∗ n ! / ( x − n ! ) y=(x-n!+n!)*n!/(x-n!) y=(xn!+n!)n!/(xn!)
y = ( x − n ! ) ∗ n ! / ( x − n ! ) + n ! 2 / ( x − n ! ) y=(x-n!)*n!/(x-n!)+n!^2/(x-n!) y=(xn!)n!/(xn!)+n!2/(xn!)
y = n ! + n ! 2 / ( x − n ! ) y=n!+n!^2/(x-n!) y=n!+n!2/(xn!)

我 们 可 以 来 分 析 一 下 这 个 公 式 : 我们可以来分析一下这个公式:
1 、 x 与 y 是 一 一 对 应 的 。 1、x与y是一一对应的。 1xy
2 、 根 据 题 目 , x 与 y 都 必 须 为 整 数 。 那 么 如 果 y 要 为 整 数 , n ! 2 / ( x − n ! ) 就 必 须 要 为 整 数 。 2、根据题目,x与y都必须为整数。那么如果y要为整数,n!^2/(x-n!) 就必须要为整数。 2xyyn!2/(xn!)
3 、 当 x − n ! 为 n ! 2 的 约 数 时 , n ! 2 / ( x − n ! ) 为 整 数 。 3、当 x-n! 为n!^{2}的约数时,n!^{2}/(x-n!) 为整数。 3xn!n!2n!2/(xn!)

又 因 为 x 可 以 取 到 任 意 整 数 , 由 此 我 们 可 以 推 出 : ( x , y ) 的 对 数 即 为 n ! 2 约 数 的 个 数 。 然 后 我 们 只 需 要 套 用 约 数 个 数 又因为x可以取到任意整数,由此我们可以推出:(x,y)的对数即为n!^2约数的个数。然后我们只需要套用约数个数 x(x,y)n!2 公 式 , 求 出 n ! 2 的 约 数 和 即 可 。 公式,求出n!^2的约数和即可。 n!2

注 : 求 约 数 个 数 的 公 式 为 注:求约数个数的公式为
N = p 1 a 1 ∗ p 2 a 2 ∗ p 3 a 3 ∗ … … ∗ p n a n N=p1^{a1}*p2^{a2}*p3^{a3}*……*pn^{an} N=p1a1p2a2p3a3pnan
n u m N = ( a 1 + 1 ) ∗ ( a 2 + 1 ) ∗ ( a 3 + 1 ) ∗ … … ∗ ( a n + 1 ) numN=(a1+1)*(a2+1)*(a3+1)*……*(an+1) numN=(a1+1)(a2+1)(a3+1)(an+1)

代码如下
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#include <algorithm>
#define LL long long
#define ULL unsigned long long
#define PII pair<int,int>
#define x first
#define y second
using namespace std;
const int N=1e6+5,mod=1e9+7;
int prime[N],cnt;
bool st[N];
void init(int n)				//线筛模板
{
    for(int i=2;i<=n;i++)
    {
        if(!st[i]) prime[cnt++]=i;
        for(int j=0;prime[j]*i<=n;j++)
        {
            st[prime[j]*i]=true;
            if(i%prime[j]==0) break;
        }
    }
}
int main()
{
    int n;
    cin>>n;
    init(n);
    int ans=1;
    for(int i=0;i<cnt;i++)			//枚举所有素数
    {
        int num=0;					//记录n!中有多少个素数prime[i]
        for(int j=n;j;j/=prime[i]) num+=j/prime[i];
        ans=(LL)ans*(2*num+1)%mod;	//因为求的是n!^2的约数,因此这里要乘(2*num+1)
    }
    cout<<ans<<endl;
    return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lwz_159

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值