思路:
概率dp。首先对n进行因子分解得到,然后每个素因子pi,计算经过k次操作之后的期望值Ei,再利用期望的性质把所有Ei乘起来得到最终结果。Ei可以通过概率dp计算,dp[i][j]表示经过i次操作之后出现的概率。
实现:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 6 const ll MOD = 1e9 + 7; 7 8 ll dp[10005][60]; 9 10 ll qpow(ll x, ll n) 11 { 12 ll res = 1; 13 while (n) 14 { 15 if (n & 1) res = res * x % MOD; 16 x = x * x % MOD; 17 n >>= 1; 18 } 19 return res; 20 } 21 22 ll inv(ll x) 23 { 24 return qpow(x, MOD - 2); 25 } 26 27 map<ll, int> fac(ll x) 28 { 29 map<ll, int> ans; 30 for (ll i = 2; i * i <= x; i++) 31 { 32 while (x % i == 0) 33 { 34 x /= i; 35 ans[i]++; 36 } 37 } 38 if (x != 1) ans[x] = 1; 39 return ans; 40 } 41 42 int main() 43 { 44 ll n; int k; 45 while (cin >> n >> k) 46 { 47 map<ll, int> ans = fac(n); 48 ll res = 1; 49 for (auto it: ans) 50 { 51 memset(dp, 0, sizeof dp); 52 ll tmp = it.first; int cnt = it.second; 53 dp[0][cnt] = 1; 54 for (int i = 1; i <= k; i++) 55 { 56 dp[i][cnt] = dp[i - 1][cnt] * inv(cnt + 1) % MOD; 57 for (int j = cnt - 1; j >= 0; j--) 58 { 59 dp[i][j] = dp[i][j + 1]; 60 dp[i][j] = (dp[i][j] + dp[i - 1][j] * inv(j + 1)) % MOD; 61 } 62 } 63 ll sum = 0; 64 for (int i = 0; i <= cnt; i++) 65 { 66 sum = (sum + dp[k][i] * qpow(tmp, i) % MOD) % MOD; 67 } 68 res = res * sum % MOD; 69 } 70 cout << res << endl; 71 } 72 return 0; 73 }
原文地址:https://www.cnblogs.com/wangyiming/p/10229100.html
时间: 2024-10-14 03:20:05