CF708E题解

考虑 \(f(n,x,y)\) 表示第 \(n\) 行左边被删了 \(x\) 个右边被删了 \(y\) 个的概率。

考虑用所有方案减去不连通的,\(g(x,y)\) 表示某行左边被删 \(x\) 个右边被删 \(y\) 个的的概率,\(S(n)=\sum_{x+y<m}f(n,x,y)\)有:

\[f(n,x,y)=g(x,y)(S(n-1)-\sum_{Y\geq m-x\or X\geq m-y}f(n-1,X,Y)) \]

容易发现 \(g\) 的定义中左边和右边没有任何关系,所以可以写成 \(g(x,y)=P(x)P(y)\),稍微写写有:

\[P(n)=\binom{k}{n}p^n(1-p)^{k-n} \]

容易发现 \(f\) 的转移具有对称性,这样会导致 \(f(n,x,y)=f(n,y,x)\)。(\(g\) 也一样)

\(F(n,k)=\sum_{x\geq k}f(n,x,y)\)

可以重写转移:

\[f(n,x,y)=P(x)P(y)(S(n-1)-F(n-1,m-x)-F(n-1,m-y)) \]

考虑对 \(F\) 进行转移而不是 \(f\)

容易发现 \(S(n)\) 相当于 \(F(n,0)\)

重新设 \(F(n,k)=\sum_{y=k}f(n-1,x,y)\),这样就只需要最后处理一个后缀和即可。

\[F(n,x)=\sum_{y=0}^{m-x-1}P(x)P(y)(S(n-1)-F(n-1,m-x)-F(n-1,m-y))=P(x)(S(n-1)-F(n-1,m-x))\sum_{y=0}^{m-x-1}P(y)-P(x)\sum_{y=0}^{m-x-1}P(y)F(n-1,m-y) \]

随便前缀和优化一下即可,复杂度 \(O(nm)\)

初始值 \(F(0,0,0)=1\),答案为 \(S(n)\)

题外话,这题不值 *3100 吧。

#include<cstdio>
namespace SOLVE{
	const int M=1505,mod=1e9+7;
	int n,m,k,p,P[M],F[M],G[M],S1[M],S2[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 void main(){
		scanf("%d%d%d%d%d",&n,&m,S1,S2,&k);p=1ll*S1[0]*pow(S2[0])%mod;S1[0]=pow(mod+1-p,k);S2[0]=0;
		const int&q=1ll*p*pow(mod+1-p)%mod;for(int i=1;i<m;++i)S1[i]=1ll*S1[i-1]*q%mod;
		if(2*k<m)return printf("1"),void();if(p==1)return printf("0"),void();
		P[0]=P[1]=1;for(int i=2;i<m&&i<=k;++i)P[i]=1ll*(mod-mod/i)*P[mod%i]%mod;
		for(int i=1;i<m&&i<=k;++i)P[i]=1ll*(k-i+1)*P[i]%mod*P[i-1]%mod;
		for(int i=0;i<m;++i)P[i]=1ll*P[i]*S1[i]%mod;S1[0]=P[0];F[0]=1;
		for(int i=1;i<m;++i)S1[i]=(S1[i-1]+P[i])%mod;
		for(int k=1;k<=n;++k){
			const int&S(F[0]);for(int i=1;i<m;++i)S2[i]=(S2[i-1]+1ll*(mod-P[i])*F[m-i])%mod;
			for(int i=0;i<m;++i)G[i]=(1ll*(S+mod-F[m-i])*S1[m-i-1]+S2[m-i-1])%mod*P[i]%mod;
			for(int i=m-1;i>=0;--i)F[i]=(G[i]+F[i+1])%mod,G[i]=0;
		}
		printf("%d",F[0]);
	} 
}
signed main(){
	SOLVE::main();
}
posted @ 2022-09-15 16:31  Prean  阅读(44)  评论(2编辑  收藏  举报
var canShowAdsense=function(){return !!0};