LOJ#6513. 「雅礼集训 2018 Day10」足球大战 题解

题目链接

首先判掉 \(p=0/1\) 或者 \(q=0/1\) 的情况。

\(x = \frac{p}{1-p},y = \frac{q}{1-q},\) 不难发现主场进 \(i\) 个球的概率为 \(\binom{n}{i} \times x^i\) , 客场进 \(i\) 个球的概率为 \(\binom{n}{i} \times y^i\)

那么直接计算概率就可以了。

实现的时候,由于空间是 \(64MB\) 所以我们只能开一个 \(O(n)\) 的数组。

可以发现我们只需要预处理阶乘的逆元。

实现要注意常数和空间。

code :

#define LL long long
const int N = 10000005,P = 1e9 + 7;
inline int power(int x,int y){
	static int r; r = 1; while (y){ if (y&1) r = (LL)r * x % P; x = (LL)x * x % P; y >>= 1; }
	return r;
}
int tmp;
int n,p,q,nfac[N],facn;
inline int C(int x){ return (LL)facn * nfac[x] % P * nfac[n-x] % P; }
int main(){
	int i,x,y;
	read(n);
	read(x),read(y),p = (LL)x * power(y,P-2) % P;
	read(x),read(y),q = (LL)x * power(y,P-2) % P;
	if (p == 0 || q == 1){ cout << 0 << '\n'; return 0; }
	if (p == 1){ cout << (1 - power(q,n) + P) % P << '\n'; return 0; }
	if (q == 0){ cout << (1 - power((1-p+P)%P,n) + P) % P << '\n'; return 0; }
	tmp = (LL)power((1-p+P)%P,n) * power((1-q+P)%P,n) % P;
	p = (LL)p * power((1-p+P)%P,P-2) % P;
	q = (LL)q * power((1-q+P)%P,P-2) % P;
	for (facn = i = 1; i <= n; ++i) facn = (LL)facn * i % P;
	for (nfac[0] = nfac[1] = 1,i = 2; i <= n; ++i) nfac[i] = (LL)(P-P/i) * nfac[P%i] % P;
	for (i = 2; i <= n; ++i) nfac[i] = (LL)nfac[i] * nfac[i-1] % P;
	int sum = 0,ans = 0,pi = 1,qi = 1;
	for (i = 0; i <= n; ++i){
		ans = (ans + (LL)sum * C(i) % P * pi) % P;
		sum = (sum + (LL)C(i) * qi) % P;
		pi = (LL)pi * p % P,qi = (LL)qi * q % P;
	}
	ans = (LL)ans * tmp % P;
	cout << ans << '\n';
	return 0;
}
posted @ 2020-09-05 19:45  srf  阅读(203)  评论(0编辑  收藏  举报