Codeforces 1097D Makoto and a Blackboard

190 篇文章 2 订阅
84 篇文章 2 订阅

题面

题意

给出n,k,每次操作会在n的所有因数中随机选择一个,然后将n替换为这个因数,问经过k次操作后,n的期望值是多少。

做法

我们可以计算出经过k次操作后,n的每个质因子还有几个,比如将n分解质因数后得到 2 5 ∗ 3 2 ∗ 4 2 2^5*3^2*4^2 253242
则我们可以用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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值