• [CF1097D] Makoto and a Blackboard


    [CF1097D] Makoto and a Blackboard - dp,质因数分解

    Description

    给定 n,k,一共有 k 次操作,每次会把 n 等概率变成 n 的某个约数。求操作 k 次后 n 的期望是多少。

    Solution

    (h[i][j]) 表示 (n=i, k=j) 的结果

    每个质因子的贡献实际上是独立的,反应在次数上就是相乘的关系

    因此,每个质因子分别贡献,总答案为乘积

    现在对于每个质因子分别算即可

    对于 p,设 (f[i][j]) 表示 (n=p^i, k=j) 的结果,那么 (f[i][j]=frac {1}{i+1} sum_{k=0}^j f[k][j-1])

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int mod = 1e9 + 7;
    int f[60][10005];
    
    int qpow(int p, int q)
    {
        return (q & 1 ? p : 1) * (q ? qpow(p * p % mod, q / 2) : 1) % mod;
    }
    
    int solve(int p, int i, int j)
    {
        if (f[i][j])
            return f[i][j];
        if (i == 0)
            return f[i][j] = 1;
        if (j == 0)
            return f[i][j] = qpow(p, i);
        f[i][j] = 0;
        for (int k = 0; k <= i; k++)
            f[i][j] += solve(p, k, j - 1);
        return f[i][j] = f[i][j] % mod * qpow(i + 1, mod - 2) % mod;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        int n, k;
        cin >> n >> k;
        int ans = 1;
        for (int i = 2; i * i <= n; i++)
            if (n % i == 0)
            {
                int cnt = 0;
                while (n % i == 0)
                    n /= i, ++cnt;
                memset(f, 0, sizeof f);
                ans *= solve(i, cnt, k);
                ans %= mod;
            }
        memset(f, 0, sizeof f);
        if (n > 1)
            ans *= solve(n, 1, k);
        ans %= mod;
        cout << ans << endl;
    }
    
  • 相关阅读:
    跳跃游戏1,2
    重叠子区间问题
    最长公共子序列问题
    由leetcode俄罗斯套娃信封问题到C++的sort()函数学习
    一道笔试题,做的很垃圾
    Spring boot框架快速入门
    Redis常用数据类型及其对应的底层数据结构
    Java 类加载机制及双亲委派模型
    Java面试高频知识点总结 part3
    Spring框架专题
  • 原文地址:https://www.cnblogs.com/mollnn/p/14408267.html
Copyright © 2020-2023  润新知