【阶乘质因数分解 && 数学】51Nod - 1189 阶乘分数

Step1 Problem:

1/N! = 1/X + 1/Y (0 < x <= y), 给你 N, 求满足条件的整数解的数量 Mod 1e9+7。
例: N = 2, 1/2 = 1/3 + 1/6, 1/2 = 1/4 + 1/4

Step2 Ideas:

学习博客
1/N! = 1/X + 1/Y -> (N!)^2 = (N! - X) * (N! - Y)
X = X1 + N!, X1 是 (N!)^2 的约(因)数,就一定存在对应的 Y 满足等式。
所以我们要求出 (n!)^2 的约(因)数个数 ans,由于 (0 < X <= Y),所以 (ans+1)/2 为结果。
自然数 N = P1^a1*P2^a2*P3^a3……Pn^an,那么它的正因数个数为:σ(n) = (1 + a1)*(1 + a2)…(1 + an)
N = P1^a1*P2^a2*P3^a3……Pn^an,N^2 = P1^(2*a1)*P2^(2*a2)*P3^(2*a3)……Pn^(2*an)
求 N!的质因数分解:
例如:对 10! 的分解质因数
1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10
1~10 里面的素数就是质因数,然后我们求它的幂即可。
质因数:2 3 5 7
10 / 2 = 5,5 个数质因数里面有 1 个 2
10 / 4 = 2,2 个数质因数里面有 2 个 2
10 / 8 = 1,1 个数质因数里面有 3 个 2
2 的幂 = 5 + 2 + 1 = 8;
10 / 3 = 3,3 个数质因数里面有 1 个 3
10 / 9 = 1,1 个数质因数里面有 2 个 3
3 的幂 = 3 + 1 = 4;
10 / 5 = 2,2 个数质因数里面有 1 个 5
5 的幂 = 2;
10 / 7 = 1,1 个数质因数里面有 1 个 7
7 的幂 = 1;
10!= 2^8 * 3^4 * 5^2 * 7.

Step3 Code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e6;
const int MOD = 1e9+7;
int prim[N], top, vis[N+5];
void get_prim()
{
    top = 0;
    memset(vis, 0, sizeof(vis));
    vis[0] = vis[1] = 1;
    for(int i = 2; i <= N; i++)
    {
        if(!vis[i]) {
            prim[top++] = i;
            for(int j = 2*i; j <= N; j += i) {
                vis[j] = 1;
            }
        }
    }
}
ll Pow(ll x, int m)
{
    ll sum = 1;
    while(m)
    {
        if(m&1) sum *= x, sum%=MOD;
        x = x*x, x%=MOD;
        m >>= 1;
    }
    return sum;
}
int main()
{
    ll n;
    get_prim();
    scanf("%lld", &n);
    memset(vis, 0, sizeof(vis));
    ll ans = 1;
    for(int i = 0; prim[i] <= n; i++)
    {
        for(ll j = prim[i]; j <= n; j *= prim[i])//这里会爆int
            vis[prim[i]] += n/j;
    }
    for(int i = 0; prim[i] <= n; i++)
    {
        ans *= (1LL*2*vis[prim[i]]+1)%MOD;
        ans %= MOD;
    }
    printf("%lld\n", (ans+1)*Pow(2, MOD-2)%MOD);//除法要逆元
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值