题解
你考虑暴力怎么做。
用 (f_{i,l,r}) 表示到达第 (i) 行,左右边界为 (l) 到 (r) 时联通的概率,那么状态转移式是:
[f_{i,l,r}= ext{cal}(l,r)cdotsum_{[l',r']cap[l,r]
eempty}f_{i-1,l',r'}
]
然后这个东西直接做必然是 (O(nm^2)) 的,非常不优美,所以我们要考虑优化。
我们观察这个转移式的求和,发现其可以被拆成三个求和式的互相加减,即
[f_{i,l,r}= ext{cal}(l,r)cdot(sum f_{i-1,l',r'}-sum_{r'<l}f_{i-1,l',r'}-sum_{l'>r}f_{i-1,l',r'})
]
我们定义
[F(i)=sum f_{i,l,r}\
L(i,j)=sum_{r<j}f_{i,l,r}\
R(i,j)=sum_{l>j}f_{i,l,r}
]
即
[f_{i,l,r}= ext{cal}(l,r)cdot(F(i-1)-L(i-1,l)-R(i-1,r))
]
可以比较轻易的得到, (L(i,j)=R(i,m-j+1)) ,所以式子又变成了
[f_{i,l,r}= ext{cal}(l,r)cdot(F(i-1)-L(i-1,l)-L(i-1,m-r+1))
]
那我们最后的答案就是 (F(n)) 。
考虑我们定义的这几个东西怎么转移。
我们再定义
[L'(i,j)=sum_{r=j}f_{i,l,r}
]
那么显然
[L(i,j)=sum_{k<j}L'(i,k)\
F(i)=sum L'(i,k)
]
我们再考虑如何求我们再定义的这个东西,我们将 (f) 的转移式子带进去。
[L'(i,j)=sum_{r=j}f_{i,l,r}\
=sum_{r=j} ext{cal}(l,r)cdot(F(i-1)-L(i-1,l)-L(i-1,m-r+1))\
=sum_{lle j} ext{cal}(l,j)cdot(F(i-1)-L(i-1,l)-L(i-1,m-j+1))\
]
发现不是很好搞了,我们考虑再定义一个前缀和
[ ext{cal}'(i,j)=sum_{l=i}^j ext{cal}(l,j)
]
这个东西可以在一开始预处理好,复杂度是 (O(m^2)) 的。
然后继续推
[L'(i,j)=(F(i-1)-L(i-1,m-j+1))cdot ext{cal}'(1,j)-sum_{lle j} ext{cal}(l,j)cdot L(i-1.l)\
=(F(i-1)-L(i-1,m-j+1))cdot ext{cal}'(1,j)-sum_{lle j} ext{cal}(l,j)cdotsum_{k<l}L'(i-1,k)\
=(F(i-1)-L(i-1,m-j+1))cdot ext{cal}'(1,j)-sum_{k<j}L'(i-1,k)cdot ext{cal}'(k+1,j)\
]
我不行了。
高啊,应该把 ( ext{cal}) 拆开来搞。
[ ext{cal}(l,r)=func(l-1)cdot func(m-r)\
L'(i,j)=sum_{lle j} ext{cal}(l,j)cdot(F(i-1)-L(i-1,l)-L(i-1,m-j+1))\
=func(m-j)((F(i-1)-L(i-1,m-j+1))cdotsum_{lle j}func(l-1)-sum_{lle j}func(l-1)cdot L(i-1,l)))
]
然后求一下 (sum_{lle j}func(l-1)) 和 (sum_{lle j}func(l-1)cdot L(i-1,l)) 即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1505,T=1e5+5;
const int MOD=1e9+7;
int n,m,a,_a,b,t;
int frac[T],ifrac[T];
int ksm(int x,int k){
int res=1;
for(;k;k>>=1,x=x*x%MOD)
if(k&1) res=res*x%MOD;
return res;
}
int C(int n,int m){
if(n<m||n<0||m<0) return 0;
return frac[n]*ifrac[m]%MOD*ifrac[n-m]%MOD;
}
int f[N],g[N],h[N],func[T],sum[N];
signed main(){
cin>>n>>m>>a>>b>>t;
a=a*ksm(b,MOD-2)%MOD,_a=(1-a+MOD)%MOD;
frac[0]=1;
for(int i=1;i<=t;++i) frac[i]=frac[i-1]*i%MOD;
ifrac[t]=ksm(frac[t],MOD-2);
for(int i=t;i>=1;--i) ifrac[i-1]=ifrac[i]*i%MOD;
for(int i=0;i<=t;++i) func[i]=C(t,i)*ksm(a,i)%MOD*ksm(_a,t-i)%MOD;
for(int i=1;i<=m;++i) sum[i]=(sum[i-1]+func[i-1])%MOD;
g[m]=1;
for(int i=1;i<=m+1;++i) f[i]=(f[i-1]+g[i-1])%MOD;
for(int i=1;i<=m;++i) h[i]=(h[i-1]+f[i]*func[i-1])%MOD;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j) g[j]=((f[m+1]-f[m-j+1]+MOD)*sum[j]%MOD-h[j]+MOD)%MOD*func[m-j]%MOD;
for(int j=1;j<=m+1;++j) f[j]=(f[j-1]+g[j-1])%MOD;
for(int j=1;j<=m;++j) h[j]=(h[j-1]+f[j]*func[j-1])%MOD;
}
return printf("%lld
",f[m+1]),0;
}