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]);
}
posted @ 2020-06-03 09:23  Shiina_Mashiro  阅读(165)  评论(0编辑  收藏  举报