I Liked Matrix!

题目大意

有一个矩形,每个位置权值为0或1。每个位置变成0或1的概率比为x:y。
设Bi表示一行1的个数。
求E(min{Bi})

容斥

设f[i]表示一行有>=i个1的概率。
设zero和one表示一个位置是0或1的概率。
显然 f[i]=f[i1]Ci1monei1zeromi+1
我们枚举min{Bi},然后想办法统计概率,假如枚举的是i,贡献是
i(f[i]nf[i+1]n)
因为一定要最小值是i,所以就是>=i减去全部>i,就一定有i。

#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int mo=1000000007,maxn=200000+10;
int f[maxn],fac[maxn],inv[maxn];
int i,j,k,l,t,n,m,x,y,ans,zero,one;
int quicksortmi(int x,int y){
    if (!y) return 1;
    int t=quicksortmi(x,y/2);
    t=(ll)t*t%mo;
    if (y%2) t=(ll)t*x%mo;
    return t;
}
int C(int n,int m){
    return (ll)fac[n]*inv[m]%mo*inv[n-m]%mo;
}
int main(){
    freopen("past.in","r",stdin);freopen("past.out","w",stdout);
    scanf("%d%d%d%d",&n,&m,&x,&y);
    zero=(ll)x*quicksortmi(x+y,mo-2)%mo;
    one=(ll)y*quicksortmi(x+y,mo-2)%mo;
    fac[0]=1;
    fo(i,1,m) fac[i]=(ll)fac[i-1]*i%mo;
    inv[m]=quicksortmi(fac[m],mo-2);
    fd(i,m-1,0) inv[i]=(ll)inv[i+1]*(i+1)%mo;
    f[0]=1;
    fo(i,1,m) f[i]=(f[i-1]-(ll)C(m,i-1)*quicksortmi(one,i-1)%mo*quicksortmi(zero,m-i+1)%mo)%mo;
    fo(i,1,m-1){
        t=(quicksortmi(f[i],n)-quicksortmi(f[i+1],n))%mo;
        (ans+=(ll)t*i%mo)%=mo;
    }
    (ans+=(ll)quicksortmi(f[m],n)*m%mo)%=mo;
    ans=(ll)ans*quicksortmi(x+y,(int)((ll)n*m%(mo-1)))%mo;
    (ans+=mo)%=mo;
    printf("%d\n",ans);
}

你可能感兴趣的:(容斥原理,概率与期望)