CF1151F Sonya and Informatics (probability expectations, DP, fast power matrix)

Obviously the result of water problems did not cut down the chi ...... ......

First Order number $ c $ $ $ sequence is 0, then the sorted sequence is certainly a front $ c $ $ $ 0, $ a rear NC $ $ $ 1.

So you can on the DP. (Actually stuck in here ......)

$ F [i] [j] $ $ I $ denotes after operations, before the number of $ c $ has a number of $ $ $ 0 $ J program. The answer is $ \ dfrac {f [k] [c]} {\ sum f [k] [i]} $.

The advantage of this is that the state can be obtained directly following values:

  • $ C $ before the number is the number of 1 $ $ $ $ CJ
  • The number after the number of $ c $ $ $ 0 to $ $ CJ
  • After the number of the number of $ c $ $ $ 1 to $ n-2c + j $ (so $ j \ ge 2c-n $)

Initial State: The initial sequence order number in front $ c $ $ $ 0 for the number of $ cnt $, then $ f [0] [cnt] = 1 $, other $ f [0] [i] = 0 $.

Transfer:

$$ f [i] [j] + = f [i-1] [j] (\ dfrac {c (c-1)} {2} + \ dfrac {(nc) (nc-1)} {2} + j (cj) + (cj) (n-2c + j)) $$

The first bracket is a front $ c $ exchange, after the second NC $ a $ exchange, the third is in front of and behind the $ $ $ 0 $ 0 exchange, in front of the fourth $ 1 and $ $ 1 $ exchange behind.

$$f[i][j]+=f[i-1][j-1](c-j+1)^2$$

$ C $ 0 $ before and after the NC $ $ $ a in one exchange of $ 1 $.

$$ f [i] [j] + = f [i-1] [j + 1] (j + 1) (n-j + 1 + 2c) $$

$ C $ 1 $ front and the rear of a $ NC $ 0 $ $ $ a in exchange.

Then Discovery $ I $ layers and the $ i-1 $ relevant layer, it can be quickly Power matrix.

Time complexity $ O (n ^ 3 \ log k) $.

#include<bits/stdc++.h>
using namespace std;
const int maxn=101,mod=1000000007;
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
    char ch=getchar();int x=0,f=0;
    while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
    while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    return f?-x:x;
}
int n,k,a[maxn],c,cnt;
inline int add(int a,int b){return a+b<mod?a+b:a+b-mod;}
inline int sub(int a,int b){return a<b?a-b+mod:a-b;}
inline int mul(int a,int b){return 1ll*a*b%mod;}
inline int qpow(int a,int b){
    int ans=1;
    for(;b;b>>=1,a=mul(a,a)) if(b&1) ans=mul(ans,a);
    return ans;
}
struct matrix{
    int a[maxn][maxn];
    matrix(){MEM(a,0);}
    matrix operator*(const matrix &t)const{
        matrix ans;
        FOR(i,0,c) FOR(k,0,c) FOR(j,0,c) ans.a[i][j]=add(ans.a[i][j],mul(a[i][k],t.a[k][j]));
        return ans;
    }
}beg,fac,ans;
matrix qpow(matrix a,int b){
    matrix ans;
    FOR(i,0,c) ans.a[i][i]=1;
    for(;b;b>>=1,a=a*a) if(b&1) ans=ans*a;
    return ans;
}
int main(){
    n=read();k=read();
    FOR(i,1,n) a[i]=read(),c+=!a[i];
    FOR(i,1,c) cnt+=!a[i];
    beg.a[cnt][0]=1;
    FOR(i,0,c){
        fac.a[i][i]=(1ll*c*(c-1)/2+1ll*(n-c)*(n-c-1)/2+1ll*i*(c-i))%mod;
        if(i>=2*c-n) fac.a[i][i]=add(fac.a[i][i],mul(c-i,n-2*c+i));
        if(i) fac.a[i][i-1]=mul(c-i+1,c-i+1);
        if(i!=c && i+1>=2*c-n) fac.a[i][i+1]=mul(i+1,n-2*c+i+1);
    }
    ans=qpow(fac,k)*beg;
    int s=0;
    FOR(i,0,c) s=add(s,ans.a[i][0]);
    s=mul(qpow(s,mod-2),ans.a[c][0]);
    printf("%d\n",s);
}
View Code

 

Guess you like

Origin www.cnblogs.com/1000Suns/p/11116040.html