CF 1097D - Hello 2019 D題: Makoto and a Blackboard
阿新 • • 發佈:2019-01-05
目錄
(有任何問題歡迎留言或私聊 && 歡迎交流討論哦
Catalog
Problem:傳送門
原題目描述在最下面。
給一個數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; }