CF708E Student's Camp
Link
设\(f_{i,j,k}\)表示只考虑前\(i\)行,这\(i\)行都连通,且第\(i\)行剩下的瓷砖区间为\([j,k]\)的概率。
不难得到转移\(f_{i,j,k}=p_{j,k}\sum\limits_{[l,r]\cap[j,k]\ne\emptyset}f_{i-1,l,r}\)。
其中\(p_{j,k}\)为某一行剩下瓷砖区间为\([j,k]\)的概率。
设\(q_i\)表示某一侧的瓷砖少了\(i\)个的概率,那么\(q_i={k\choose i}P^i(1-P)^{k-i}\),且\(p_{j,k}=q_{j-1}q_{m-k}\)。
直接前缀和优化转移需要\(O(nm^2)\)的时间复杂度,不太能过。
设\(g_{i,k}=\sum\limits_{j\le k}f_{i,j,k},h_{i,j}=\sum\limits_{l\le r\le j}f_{i,l,r}=\sum\limits_{k\le j}g_{i,k}\),那么我们要求的答案就是\(h_{n,m}\)。
我们有一个很好地性质是\(f_{i,j,k}=f_{i,m-k+1,m-j+1}\),那么随便画个图容斥一下可以得到
\[f_{i,j,k}=p_{j,k}\sum\limits_{[l,r]\cap[j,k]\ne\emptyset}f_{i-1,l,r}=p_{j,k}(h_{i-1,m}-h_{i-1,j-1}-h_{i-1,m-k})
\]
\[\begin{aligned}
g_{i,r}&=\sum\limits_{l\le r}f_{i,l,r}\\
&=\sum\limits_{l\le r}p_{l,r}(h_{i-1,m}-h_{i-1,l-1}-h_{i-1,m-r})\\
&=d_{m-r}(\sum\limits_{l\le r}d_{l-1}(h_{i-1,m}-h_{i-1,m-r})-\sum\limits_{l\le r}d_{l-1}h_{i-1,l-1})
\end{aligned}
\]
前缀和优化即可。
#include<cstdio>
using i64=long long;
const int N=1507,K=100007,P=1000000007;
i64 fac[K],ifac[K],pwp[K],qwq[K],d[K],sd[N],g[N][N],h[N][N],sum[N][N];
int read(){int x;scanf("%d",&x);return x;}
i64 C(int n,int m){return fac[n]*ifac[m]%P*ifac[n-m]%P;}
i64 pow(i64 a,int b){i64 r=1;for(;b;b>>=1,a=a*a%P)if(b&1)r=r*a%P;return r;}
int main()
{
int n=read(),m=read(),a=read(),b=read(),k=read(),pr=a*pow(b,P-2)%P,qr=(P+1-pr)%P;
fac[0]=1;for(int i=1;i<=k;++i) fac[i]=i*fac[i-1]%P;
ifac[k]=pow(fac[k],P-2);for(int i=k;i;--i) ifac[i-1]=i*ifac[i]%P;
pwp[0]=1;for(int i=1;i<=k;++i) pwp[i]=pr*pwp[i-1]%P;
qwq[0]=1;for(int i=1;i<=k;++i) qwq[i]=qr*qwq[i-1]%P;
for(int i=0;i<=k;++i) d[i]=C(k,i)*pwp[i]%P*qwq[k-i]%P;
for(int i=1;i<=m;++i) sd[i]=(sd[i-1]+d[i-1])%P;
g[0][m]=h[0][m]=1;for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) g[i][j]=(sd[j]*(h[i-1][m]-h[i-1][m-j]+P)-sum[i-1][j]+P)%P*d[m-j]%P,h[i][j]=(h[i][j-1]+g[i][j])%P,sum[i][j]=(sum[i][j-1]+d[j-1]*h[i][j-1])%P;
printf("%lld",h[n][m]);
}