hdu6842.Battle for Wosneth2/百度之星2020复赛1005

题目描述

题解

因为被BC搞死了所以没有切掉

菜得真实.jpg


先把pq变成概率

\(f[i][j]\)表示B的生命为i,A的生命为j时A先手的存活概率(反过来的话推出来的式子每次要加常数项搞不了),初值为\(f[0][j]=1\)

当j=0的时候也是1,可以理解成A先手所以赢了,主要是方便\(f[1][1]的\)计算(写出来发现是对的)

\(F_i(x)=\sum_j f[i][j]x^j\),那么有转移

\(F_i(x)=p(1-q)F_{i-1}(x)+pqF_{i-1}(x)x+(1-p)(q)F_i(x)x+(1-p)(1-q)F_i(x)\)

简化式子得到

\((1-Cx-D)F_i(x)=(Ax+B)F_{i-1}(x)\)

\(F_i(x)=\frac{Ax+B}{1-Cx-D}F_{i-1}(x)\)

初值\(F_0(x)=\sum_i x^i=\frac{1}{1-x}\),求的是\(F_m(x)[x^n]\),把上下展开暴力卷即可,初值的\(\frac{1}{1-x}\)相当于对\(\frac{1}{Cx+D}\)做前缀和

这样有个问题,\(f[1][0]\)的值本应该是0但算出来的是B,考虑对\(F_1(x)\)特殊处理

\(F_1(x)=(Ax+B)F_0(x)-B+(Cx+D)F_1(x)\)

\(F_1(x)=\frac{Ax+B}{1-Cx-D}F_0(x)-\frac{B}{1-Cx-D}\)

形式类似,去掉前缀和即可

时间复杂度O(n+m)

code

#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define C(n,m) (jc[n]*Jc[m]%998244353*Jc[(n)-(m)]%998244353)
#define add(a,b) a=((a)+(b))%998244353
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define mod 998244353
#define Mod 998244351
#define ll long long
#define N 200000
//#define file
using namespace std;

ll a[N+1],b[N+1],jc[N+1],Jc[N+1],A2[N+1],B2[N+1],C2[N+1],f[51][51],p,q,A,B,C,D;
int T,n,m,i,j,k,l;

ll qpower(ll a,int b) {ll ans=1; while (b) {if (b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;} return ans;}
ll js(int n,int m1,int m2,bool bz)
{
	int i,j,k,l;
	ll ans=0;
	memset(a,0,(n+1)*8);
	memset(b,0,(n+1)*8);
	
	fo(i,0,min(n,m1)) a[i]=A2[i]*B2[m1-i]%mod*C(m1,i)%mod;
	fo(i,0,n) b[i]=C2[i]*C(i+m2-1,m2-1)%mod;
	if (bz) fo(i,1,n) b[i]=(b[i]+b[i-1])%mod;
	
	fo(i,0,n) ans=(ans+a[i]*b[n-i])%mod;
	return ans;
}

int main()
{
	#ifdef file
	freopen("e.in","r",stdin);
	#endif
	
	jc[0]=1;
	fo(i,1,N) jc[i]=jc[i-1]*i%mod;
	Jc[N]=qpower(jc[N],Mod);
	fd(i,N-1,0) Jc[i]=Jc[i+1]*(i+1)%mod;
	
	scanf("%d",&T);
	for (;T;--T)
	{
		scanf("%d%d%lld%lld",&n,&m,&p,&q);
		p=p*qpower(100,Mod)%mod,q=q*qpower(100,Mod)%mod;
		A=p*q%mod,B=p*(1-q)%mod,C=(1-p)*q%mod,D=(1-p)*(1-q)%mod;
		D=qpower(1-D,Mod),A=A*D%mod,B=B*D%mod,C=C*D%mod;
		A2[0]=B2[0]=C2[0]=1;
		fo(i,1,max(n,m)) A2[i]=A2[i-1]*A%mod,B2[i]=B2[i-1]*B%mod,C2[i]=C2[i-1]*C%mod;
		printf("%lld\n",((js(n,m,m,1)-js(n,m-1,m,0)*B)%mod+mod)%mod);
	}
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}
posted @ 2020-08-10 15:10  gmh77  阅读(281)  评论(0编辑  收藏  举报