Codeforces 1097D Makoto and a Blackboard

題面

題意

給出n,k,每次操作會在n的所有因數中隨機選擇一個,然後將n替換爲這個因數,問經過k次操作後,n的期望值是多少。

做法

我們可以計算出經過k次操作後,n的每個質因子還有幾個,比如將n分解質因數後得到2532422^5*3^2*4^2
則我們可以用dp分別計算出經過k次操作後,n變成了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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章