华华送奕奕小礼物

https://ac.nowcoder.com/acm/contest/894/B

推公式+矩阵快速幂

1、假设在第 i 次后剩下 a_i 个黑球,那么第 i+1 次操作后黑球数 a_{i+1} 公式如下:

a_{i+1}=p*( \frac {a_i+1}{n+m+1}*a_i+ \frac {n+m+1-(a_i+1)}{n+m+1}*(a_i+1))+\\\\(1-p)*( \frac {a_i}{n+m+1}*(a_i-1)+ \frac {n+m+1-a_i}{n+m+1}*a_i)

2、有概率 p 放入黑球,取出的球是黑球的概率为 \frac {a_i+1}{n+m+1} ,剩余黑球数量的期望是 a_i,同理推出其他

3、得到递推式 a_{i+1}=(p+a_i)* \frac{n+m}{n+m+1}=a_i* \frac{n+m}{n+m+1}+p* \frac{n+m}{n+m+1}

4、考虑矩阵快速幂,令   k =p* \frac{n+m}{n+m+1}bas= \frac {n+m}{n+m+1}

\begin{pmatrix} a_i & k \\ 0 & 0 \end{pmatrix} \begin{pmatrix} bas & 0 \\ k & 1 \end{pmatrix}= \begin{pmatrix} a_{i+1} & k \\ 0 & 0 \end{pmatrix}

code:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int len = 2;
const ll mod = 1e9 + 7;
struct node
{
	ll martix[len][len];
	void zero()
	{
		memset(martix, 0, sizeof(martix));
	}
	void one()
	{
		for (int i = 0; i < len; i++)
			for (int j = 0; j < len; j++)
				if (i == j)
					martix[i][j] = 1;
				else
					martix[i][j] = 0;
	}
	void set(ll temp[len][len])
	{
		for (int i = 0; i < len; i++)
			for (int j = 0; j < len; j++)
				martix[i][j] = temp[i][j];
	}
	node operator *(const node& o)
	{
		node ans;
		ans.zero();
		for (int i = 0; i < len; i++)
			for (int j = 0; j < len; j++)
				for (int k = 0; k < len; k++)
					ans.martix[i][k] = (ans.martix[i][k] + martix[i][j] * o.martix[j][k]) % mod;
		return ans;
	}
};
ll power(ll a, ll b)
{
	ll res = 1;
	while (b)
	{
		if (b & 1)
			res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}
node power(node a, ll b)
{
	node res;
	res.one();
	while (b)
	{
		if (b & 1)
			res = res * a;
		a = a * a;
		b >>= 1;
	}
	return res;
}
int main()
{
	ll n, m, k, a, b;
	scanf("%lld%lld%lld%lld%lld", &n, &m, &k, &a, &b);
	ll p = a * power(b, mod - 2) % mod;
	ll q = (n + m) * power(n + m + 1, mod - 2) % mod;
	p = p * q % mod;
	ll pres[len][len] = {
		{n,p},
		{0,0}
	};
	ll t[len][len] = {
		{q,0},
		{1,1}
	};
	node temp;
	temp.set(t);
	node pre;
	pre.set(pres);
	temp = power(temp, k);
	pre = pre * temp;
	printf("%lld\n", pre.martix[0][0]);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值