CF 1097D - Hello 2019 D题: Makoto and a Blackboard

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

Catalog

Problem:传送门

Portal

 原题目描述在最下面。

 给一个数n,由k次操作。每次操作等概率的把n变成他的一个因数(\(1\leq x\leq n\)),问k次操作后得到的数的期望是多少。


Solution:

\(n = p1^{a1}*...*pm^{am}\)
积性函数: \(fk(n) = fk(p1^{a1})*...*fk(pm^{am})\)
\(dp[j]\) 表示\(pi^j\)执行\(k\)次操作之后的结果的期望
\(dp[j] = sigma(dp[j-1])/yinzi\_num\)
\(yinzi\_num = j+1\)


AC_Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MXN = 1e6 + 7;
const int INF = 0x3f3f3f3f;
const LL mod = 1000000007;
const LL MOD = 5631653553151;

LL n;
int k;
LL inv[MXN];
LL calc(LL x, int p) {
    std::vector<LL> dp(p+1);
    dp[0] = 1;
    for(int i = 1; i <= p; ++i) {
        dp[i] = dp[i-1] * x % mod;
    }
    for(int t = 0; t < k; ++t) {
        for(int i = 1; i <= p; ++i) dp[i] = (dp[i-1]+dp[i]) % mod;
        for(int i = 1; i <= p; ++i) dp[i] = dp[i] * inv[i+1] % mod;
    }
    return dp[p];
}
int main() {
    inv[1] = 1;
    for(int i = 2; i < MXN; ++i) inv[i] = inv[mod%i]*(mod-mod/i)%mod;
    scanf("%lld%d", &n, &k);
    LL tn = n, ans = 1;
    int cnt;
    for(LL i  = 2; i * i <= n; ++i) {
        if(tn % i == 0) {
            cnt = 0;
            while(tn % i == 0) tn /= i, ++ cnt;
            ans *= calc(i, cnt);
            //printf("%lld %d\n", i, cnt);
            if(ans >= mod) ans %= mod;
        }
        if(tn == 1) break;
    }
    if(tn > 1) {
        ans *= calc(tn, 1);
    }
    printf("%lld\n", ans % mod);
    return 0;
}

Problem Description:

在这里插入图片描述

posted @ 2019-01-05 18:10  Cwolf9  阅读(232)  评论(0编辑  收藏  举报