CF1194F Crossword Expert (number theory, combinatorics)

Not difficult a problem. I do not know why can $ 2500 $ ......

But the court will not push the wrong has been optimized ......

Consider first $ f_i $ represents the probability of exactly done before the $ i $-question.

Making it difficult to count. Modify, $ f_i $ express finished probability of at least $-question $ i.

The answer is $ \ sum \ limits_ {i = 0} ^ ni (f_i-f_ {i + 1}) = \ sum \ limits_ {i = 1} ^ nf_i $.

Since each question can only be used up more than one second, consider the $ dp [i] [j] $ for the first $ i $ questions exactly SB $ j $ time probability.

The initial state is $ dp [0] [0] = 1 $. Transfer is $ dp [i] [j] = \ dfrac {1} {2} (f [i-1] [j] + f [i-1] [j-1]) $.

See staring formula is easy to see $ dp [i] [j] = (\ dfrac {1} {2}) ^ i \ dbinom {i} {j} $. Not difficult to understand the actual meaning.

(Where the field is pushed become $ (\ dfrac {1} {2}) ^ {i + j} \ dbinom {i + j} {i} $ ...... on the self-closing)

Then there is $ f_i = \ sum \ limits_ {j = 0} ^ {r_i} dp [i] [j] = (\ dfrac {1} {2}) ^ i \ sum \ limits_ {j = 0} ^ {r_i } \ dbinom {i} {j} $. Where $ r_i = T- \ sum \ limits_ {j = 1} ^ it_j $, SB represents the maximum allowed times. (In fact, to take a $ i $ and $ \ min $, but does not affect, you can think about why)

Question is seeking $ \ sum \ limits_ {j = 0} ^ {r_i} \ dbinom {i} {j} $ a. Next is a very wonderful practice.

Direct violence when first $ i = 1 $.

Then $ \ sum \ limits_ {j = 0} ^ {r_i} \ dbinom {i + 1} {j} = \ sum \ limits_ {j = 0} ^ {r_i} (\ dbinom {i} {j} + \ dbinom {i} {j-1}) = 2 \ sum \ limits_ {j = 0} ^ {r_i} \ dbinom {i} {j} - \ dbinom {i} {r_i} $. Direct recursion.

Because $ $ r_i monotonically decreasing, after completion of the recursive $ r_ {i + 1} + 1 $ to $ $ r_i number of combinations of the line are deleted.

Little can be done to achieve outstanding $ O (n) $.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=200020,mod=1000000007,inv2=500000004;
#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 ll read(){
    ll x=0,f=0;char ch=getchar();
    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,t[maxn],fac[maxn],inv[maxn],invfac[maxn],f[maxn],ans,pro=1;
ll r[maxn];
int C(int n,ll m){
    if(n<m) return 0;
    return 1ll*fac[n]*invfac[m]%mod*invfac[n-m]%mod;
}
int main(){
    n=read();r[0]=read();
    FOR(i,1,n) t[i]=read();
    FOR(i,1,n) r[i]=r[i-1]-t[i];
    fac[0]=fac[1]=inv[1]=invfac[0]=invfac[1]=1;
    FOR(i,2,n){
        fac[i]=1ll*fac[i-1]*i%mod;
        inv[i]=mod-1ll*(mod/i)*inv[mod%i]%mod;
        invfac[i]=1ll*invfac[i-1]*inv[i]%mod;
    }
    FOR(i,0,min(1ll,r[1])) f[1]=(f[1]+C(1,i))%mod;
    FOR(i,2,n){
        if(r[i]<0) break;
        f[i]=(2ll*f[i-1]-C(i-1,r[i-1])+mod)%mod;
        ROF(j,min<ll>(i,r[i-1]),r[i]+1) f[i]=(f[i]-C(i,j)+mod)%mod;
    }
    FOR(i,1,n){
        if(r[i]<0) break;
        pro=1ll*pro*inv2%mod;
        ans=(ans+1ll*pro*f[i])%mod;
    }
    printf("%d\n",ans);
}
View Code

 

Guess you like

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