题解 | F. 除数链

除数链

https://ac.nowcoder.com/acm/contest/121614/F

F. 除数链

和因子有关,直接质因数分解

我们定义 表示 ,则 表示

题目要求找到最长的除数链,我们发现对于 代表的 代表的 满足

说人话:除数链往右扫的过程中,这个 元组中,至少有一个元素增加恰好

要最长,肯定是从 变到

我们需要加 次,定义 表示加到第 个位置

问题变成给你一个 的字符串,有多少种排列方案

显然根据高中数学常识,这就是

预处理 阶乘阶乘逆元 即可

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

#define fType int
#define foreach(x, a, b) for (fType x = a, _end_ = b; x <= _end_; x++)
#define foreach_sub(x, a, b) for (fType x = a, _end_ = b; x >= _end_; x--)
#define tpl make_tuple

constexpr ll MOD = 1000000007;
constexpr ll XX = __lg(1000000000000) + 2;
ll jc[XX + 1];
void init()
{
    jc[0] = jc[1] = 1;
    foreach (i, 2, XX)
        jc[i] = jc[i - 1] * i % MOD;
}

template <ll MOD>
ll qpow(ll x, ll p)
{
    ll r = 1;
    for (; p; p >>= 1, x = x * x % MOD)
        if (p & 1) r = r * x % MOD;
    return r;
}

int main()
{
    ios::sync_with_stdio(0), cin.tie(0);

    init();

    ll n;
    cin >> n;

    vector<ll> ct;
    ct.reserve(85714);

    for (ll i = 2; i * i <= n; ++i)
    {
        if (n % i == 0)
        {
            int cnt = 0;
            while (n % i == 0)
                n /= i, ++cnt;
            ct.emplace_back(cnt);
        }
    }
    if (n > 1) ct.emplace_back(1);

    ll len = accumulate(ct.begin(), ct.end(), 0ll) + 1;
    ll u = jc[len - 1], v = 1;
    for (auto c : ct)
        v = v * jc[c] % MOD;
    cout << len << " " << u * qpow<MOD>(v, MOD - 2) % MOD << "\n";

    return 0;
}

扩展思考:如果 ,还能做吗?

全部评论

相关推荐

10-14 21:00
门头沟学院 Java
吃花椒的狸猫:这个人说的倒是实话,特别是小公司,一个实习生哪里来的那么多要求
点赞 评论 收藏
分享
11-17 14:18
门头沟学院 C++
代码飞升_不回私信人...:这种感觉还好。只是你写一个PPT,可能他面的快一点而已。那种让你写什么方案,写什么代码的那种。就没必要去了。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务