Codeforces708E Student's Camp

Description

有一个 (n+2)×m 的网格。

除了第一行和最后一行,其他每一行每一天最左边和最右边的格子都有 p 的概率消失。

k 天后,网格始终保持连通的概率。

n,m1.5×103k105,答案对 109+7 取模。

Solution

先计算 Pi=(Ki)(1p)Kipi 表示经过 k 天后在单个方向有 i 个格子消失的概率

那么设 fi,l,r 表示第 i 行剩下 l,r 且保证连通到第一行的概率,转移找上一行有交的就行了

Li,j 表示第 i 行右端点不超过 j 的所有区间 f 值之和,Ri,j 表示左端点不小于 j 的区间 f 值之和

由于矩形是对称的,那么 Li,j=Ri,mj+1

单个元素转移复杂度难以下降,同时对每个元素各自进行观察除了对称什么也得不到,所以只能尝试摸索前缀和转移是否可行

将单个元素转移式对两侧第二维求和得到

Fi,r=lr(Si1Li1,l1Li1,mr)El1Emr

其中 Si 表示第 i 行所有元素的 dp 值求和的结果,拆开分别做前缀和即可

时间复杂度 Θ(mn)

Code

const int N=2010;
int n,p,c[N],d[N][N],dp[N];
signed main(){
	n=read();
	int a=read(),b=read();
	p=mul(a,ksm(b,mod-2));
	d[1][0]=d[1][1]=1;
	for(int i=2;i<=n;i++){
		d[i][0]=1;
		for(int j=1;j<=i;j++)
			d[i][j]=(d[i-1][j]*ksm(mod+1-p,j)+d[i-1][j-1]*ksm(p,i-j))%mod;
	}
	for(int i=1;i<=n;i++){
		int res=0;
		for(int j=1;j<i;j++) ckadd(res,mul(c[j],d[i][j]));
		c[i]=del(1,res);
	}
	for(int i=1;i<=n;i++){
		int res=0;
		for(int j=1;j<i;j++){
			int tmp=(dp[j]+j*(i-j)+dp[i-j]+j*(j-1)/2)%mod;
			res=(res+c[j]*d[i][j]%mod*tmp)%mod;
		}
		res=(res+c[i]*d[i][i]%mod*(i*(i-1)/2))%mod;
		dp[i]=res*ksm(mod+1-c[i]*d[i][i]%mod,mod-2)%mod;
	}
	print(dp[n]);
	return 0;
}
posted @   没学完四大礼包不改名  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示