[CF1097D] Makoto and a Blackboard - dp,质因数分解
作者:互联网
[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;
}
标签:Makoto,return,因数分解,qpow,int,ans,CF1097D,mod 来源: https://www.cnblogs.com/mollnn/p/14408267.html