题面
题意
给出n,k,每次操作会在n的所有因数中随机选择一个,然后将n替换为这个因数,问经过k次操作后,n的期望值是多少。
做法
我们可以计算出经过k次操作后,n的每个质因子还有几个,比如将n分解质因数后得到
2
5
∗
3
2
∗
4
2
2^5*3^2*4^2
25∗32∗42
则我们可以用dp分别计算出经过k次操作后,n变成了
2
?
∗
3
?
∗
4
?
2^?*3^?*4^?
2?∗3?∗4?,分别计算出?的值,全部相乘即为n的期望值。
代码
#include<bits/stdc++.h>
#define ll long long
#define N 10100
#define MN 40000000
#define M 1000000007
using namespace std;
ll n,m,ans=1,dp[N][110],ny[N];
inline ll po(ll u,ll v)
{
ll res=1;
for(;v;)
{
if(v&1) res=res*u%M;
u=u*u%M;
v>>=1;
}
return res;
}
inline void calc(ll u,ll v)
{
ll i,j,k,t,res=0;
for(i=0;i<=m;i++) for(j=0;j<=u;j++) dp[i][j]=0;
dp[0][u]=1;
for(i=0;i<m;i++)
{
for(j=u;j>=0;j--)
{
for(k=0;k<=j;k++)
{
dp[i+1][k]+=dp[i][j]*ny[j+1]%M;
if(dp[i+1][k]>M) dp[i+1][k]-=M;
}
}
}
t=1;
for(i=0;i<=u;i++)
{
res+=dp[m][i]*t%M;
if(res>M) res%=M;
t=t*v%M;
}
ans*=res;
ans%=M;
}
int main()
{
ll i,j,t;
cin>>n>>m;
for(i=1;i<=100;i++) ny[i]=po(i,M-2);
for(i=2;n!=1 && i<=MN;i++)
{
if(n%i) continue;
t=0;
for(;n%i==0;t++) n/=i;
calc(t,i);
}
if(n) calc(1,n);
cout<<ans;
}