CF708E Student's Camp
传送门
题解
我莫得脑子
首先可以设(f_{i,l,r})表示现在到了第(i)行,还剩下第(l ightarrow r)个砖块,而且整个图联通的概率.
这里设
[D_i=inom{t}{i}{p}^i(1-p)^{t-i}
\
]
很明显有
[f_{i,l,r}=sum_{max(l',l)<=min(r',r)}D(l-1)D(m-r)f_{i-1,l',r'}
]
这样子转移是(O(nm^4))的,很明显会(GG).
这里我们再设(P(l,r)=D(l-1)D(m-r+1))
考虑优化,正难则反,即我们考虑转移的时候用所有的减去不合法的,即:
[f_{i,l,r}=P(l,r)(sum_{l'<=r'}f_{i-1,l',r'}-sum_{r'<l}f_{i-1,l',r'}-sum_{l'>r}f_{i-1,l',r'})
]
这里就变成了三个(sum)的计数,一个一个考虑.
设
[F(i)=sum_{l<=r}f_{i,l,r}
\
L(i,x)=sum_{r<x}f_{i,l,r}
\
R(i,x)=sum_{l>x}f_{i,l,r}
]
这个时候转移就可以写成:
[f_{i,l,r}=P(l,r)[F(i-1)-L(i-1,l)-R(i-1,r)]
]
不难发现(L_{i,x}=R_{i,m-x+1}),所以我们只需要考虑(L)的更简单的求法.
我们可以钦定
[Sl_{i,r}=sum_{l<=r}f_{i,l,r}
]
这个时候就有:
[F(i)=sum_{r=1}^mSl_{i,r}
\
L(i,x)=sum_{r<x}Sl_{i,r}
\
R(i,x)=L(i,m-x+1)=sum_{r<m-x+1}Sl_{i,r}
]
接着考虑回带,即:
[egin{align}
Sl_{i,r}&=sum_{l<=r}f_{i,l,r}
\
&=sum_{l<=r}P(l,r)[F(i-1)-sum_{r=1}^{x-1}Sl_{i-1,r}-sum_{r=1}^{m-x}Sl_{i-1,r}]
\
&=D(m-r)sum_{l=1}^{r}D(l-1)[F(i-1)-R(i-1,r)]-D(l-1)L(i-1,l)
end{align}
]
这样子转移即可.初始值(Sl_{0,m}=1),答案是(F(n)).
代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define REP(a,b,c) for(int a=b;a<=c;a++)
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
typedef pair<int,int> pii;
#define mp make_pair
inline int gi()
{
int f=1,sum=0;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
const int N=2010,M=100010,Mod=1e9+7;
int n,m,p,t,fac[M],inv[M],ifac[M],Sl[N][N],S1[M],S2[N][N],L[N][N],D[N];
int C(int n,int m){if(n<m||m<0||n<0)return 0;return 1ll*fac[n]*ifac[m]%Mod*ifac[n-m]%Mod;}
int qpow(int a,int b){int ret=1;while(b){if(b&1)ret=1ll*ret*a%Mod;b>>=1;a=1ll*a*a%Mod;}return ret;}
int main()
{
n=gi();m=gi();p=gi();p=1ll*p*qpow(gi(),Mod-2)%Mod;t=gi();
fac[0]=ifac[0]=inv[0]=inv[1]=ifac[1]=fac[1]=1;
for(int i=2;i<=100000;i++)fac[i]=1ll*fac[i-1]*i%Mod,inv[i]=1ll*(Mod-Mod/i)*inv[Mod%i]%Mod,ifac[i]=1ll*ifac[i-1]*inv[i]%Mod;
for(int i=0;i<=min(m,t);i++)D[i]=1ll*C(t,i)*qpow(p,i)%Mod*qpow((1-p+Mod),t-i)%Mod;
for(int i=1;i<=m;i++)S1[i]=(S1[i-1]+D[i-1])%Mod;
Sl[0][m]=1;L[0][m]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
Sl[i][j]=1ll*D[m-j]*(1ll*(L[i-1][m]-L[i-1][m-j]+Mod)*S1[j]%Mod-S2[i-1][j]+Mod)%Mod;
L[i][j]=(L[i][j-1]+Sl[i][j])%Mod;
S2[i][j]=(S2[i][j-1]+1ll*D[j-1]*L[i][j-1]%Mod)%Mod;
}
printf("%d
",L[n][m]);
return 0;
}