BSOJ7736题解

去年模拟赛被薄纱的题,回来看看怎么做。。。

考虑设一个回合表示 \(A,B\) 不断开枪然后有人打中的情况。

不难发现一个回合有三种情况:\((1,0),(0,1)(1,1)\)

对于三种情况我们分别计算概率为 \(p_1,p_2,p_3\),考虑计算答案。

假设 \(B\) 已经被打到只剩下一滴血了,而此时 \(A\) 还没有死,枚举 \((1,1)\) 的数量得到答案是:

\[\sum_{i=0}^{\min(n-1,m-1)}p_3^ip_2^{m-i-1}\sum_{j=0}^{n-i-1}\binom{m-1+j}{j,i,m-i-1}p_1^j \]

最后乘上 \(A\) 开出最后一枪的概率 \(p'\) 即可。

先拆组合数,这个大家伙等于 \(\binom{m-1+j}{j}\binom{m-1}{i}\)

原问题变为:

\[\sum_{i=0}^{\min(n-1,m-1)}\binom{m-1}{i}p_3^ip_2^{m-i-1}\sum_{j=0}^{n-i-1}\binom{m-1+j}{j}p_1^j \]

不难发现后面这个东西是个前缀和,稍微处理一下组合数与幂就好了。复杂度 \(O(\sum(n+m))\)

#include<cstdio>
#include<cctype>
const int M=5e6+5,mod=998244353;
int T,mx,n[10005],m[10005],q[10005],p[10005],fac[M],ifac[M];
inline int pow(int a,int b=mod-2){
	int ans(1);for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod;return ans;
}
inline int read(){
	int n(0);char s;while(!isdigit(s=getchar()));while(n=n*10+(s&15),isdigit(s=getchar()));return n;
}
inline void write(int n){
	static char s[15];int top(0);while(s[++top]=n%10^48,n/=10);while(putchar(s[top]),--top);putchar(10);
}
inline int C(const int&n,const int&m){
	return 1ll*ifac[m]*ifac[n-m]%mod*fac[n]%mod;
}
inline int Solve(const int&n,const int&m,const int&q,const int&p){
	if(q==1&&p==1)return n>=m;
	const int&k=pow(mod+1-1ll*(mod+1-q)*(mod+1-p)%mod);
	const int&p1=1ll*(mod+1-q)*p%mod*k%mod,&p2=1ll*q*(mod+1-p)%mod*k%mod,&p3=1ll*q*p%mod*k%mod;
	static int S[M];int ans(0);S[0]=1;
	for(int t(p1),i=1;i<n;++i)S[i]=(S[i-1]+1ll*C(m-1+i,i)*t)%mod,t=1ll*t*p1%mod;
	for(int x(pow(p2,m-1)),y(1ll*p3*pow(p2)%mod),i=0;i<n&&i<m;++i){
		ans=(ans+1ll*C(m-1,i)*(i==m-1?pow(p3,m-1):x)%mod*S[n-i-1])%mod;x=1ll*x*y%mod;
	}
	return 1ll*ans*k%mod*q%mod;
}
signed main(){
	const int&x=pow(100);
	scanf("%d",&T);for(int i=1;i<=T;++i)scanf("%d%d%d%d",n+i,m+i,q+i,p+i),n[i]+m[i]>mx&&(mx=n[i]+m[i]);
	fac[0]=fac[1]=ifac[0]=1;for(int i=2;i<=mx;++i)fac[i]=1ll*fac[i-1]*i%mod;
	for(int t(pow(fac[mx])),i=mx;i>=1;--i)ifac[i]=1ll*fac[i-1]*t%mod,t=1ll*t*i%mod;
	for(int i=1;i<=mx;++i)ifac[i]=1ll*ifac[i-1]*ifac[i]%mod;
	for(int i=1;i<=T;++i)write(Solve(n[i],m[i],1ll*q[i]*x%mod,1ll*p[i]*x%mod));
}
/*
3
1 1 50 50
100000 1 99 100
11 45 14 19
*/
posted @ 2022-08-25 11:44  Prean  阅读(13)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};