BZOJ 3622: there is nothing to be afraid of the combination number + Dp

title

BZOJ 3622

LUOGU 4859

Simplify the meaning of the questions:

Two columns \ (\ {A_N \} \) , \ (\ {B_n \} \) , seeking \ (a_i> b_i \) number of groups just ratio \ (b_i> a_i \) the number of set of multi \ (K \) the number of cases of group.

analysis

Ask what topics can be transformed, but also for convenience:

Order \ (K = \ + K FRAC {n-2}} {\) , i.e. there is just \ (K \) group is larger than the tablet candy ( \ (a_i> B_i \) ).

Obviously you want to \ (a_i, b_i \) in ascending order.

Consider \ (a_i \) the impact of:

  1. If \ (a_i \) matches \ (B, a_i> B \) , then for \ (a_j, J> I \) , it matches \ (B, a_j> B \) . 1 less the number of programs;
  2. If \ (a_i \) matches \ (b, a_i <b \) ...... once again be classified discussions, the state is difficult to record.

So, we \ (Dp \) when consider the first of \ (a_i \) , last second of uniform distribution.

Set \ (g_ {i, j} \) representing the forward \ (I \) a \ (A \) , there are \ (J \) th number of a first embodiment .

State transition equation is:
\ [G_ {I, J} = {I-G_. 1, J +} (r_i- (-J. 1)). 1-G_ {I, J-}. 1 (b r_i represented in less than a_i number) \]
then, we can make
\ [f_i = (ni)!
g_ {n, i} \] is the \ (Ni \) arbitrary assignment did not match, to give at least \ (I \) th The answer \ (F_i \) .

So just \ (I \) th answer can be obtained from the large to the small recursion:
\ [{J} = I + C. 1 ^ = i_jans_j ans_i f_i- \ SUM n-^ {} _ \]

code

#include<bits/stdc++.h>

typedef long long ll;
const int maxn=2110,mod=1e9+9;

namespace IO
{
    char buf[1<<15],*fs,*ft;
    inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
    template<typename T>inline void read(T &x)
    {
        x=0;
        T f=1, ch=getchar();
        while (!isdigit(ch) && ch^'-') ch=getchar();
        if (ch=='-') f=-1, ch=getchar();
        while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
        x*=f;
    }

    char Out[1<<24],*fe=Out;
    inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
    template<typename T>inline void write(T x)
    {
        if (!x) *fe++=48;
        if (x<0) *fe++='-', x=-x;
        T num=0, ch[20];
        while (x) ch[++num]=x%10+48, x/=10;
        while (num) *fe++=ch[num--];
        *fe++='\n';
    }
}

using IO::read;
using IO::write;

inline ll Quick_power(ll a,ll b)
{
    ll ans=1;
    while (b)
    {
        if (b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}

ll fac[maxn],inv[maxn];
inline ll C(int n,int m)
{
    if (m==-1) return n==-1;
    return fac[n]*inv[m]%mod*inv[n-m]%mod;
}

int a[maxn],b[maxn],r[maxn];
ll g[maxn][maxn],f[maxn],ans[maxn];
int main()
{
    int n,K;read(n);read(K);
    fac[0]=1;
    for (int i=1; i<=maxn-1; ++i) fac[i]=fac[i-1]*i%mod;
    inv[maxn-1]=Quick_power(fac[maxn-1],mod-2);
    for (int i=maxn-2; i>=0; --i) inv[i]=inv[i+1]*(i+1)%mod;

    if ((n+K)&1) return puts("0"),0;
    K=(n+K)>>1;
    for (int i=1; i<=n; ++i) read(a[i]);
    for (int i=1; i<=n; ++i) read(b[i]);
    std::sort(a+1,a+n+1);
    std::sort(b+1,b+n+1);

    for (int i=1, c=0; i<=n; ++i)
    {
        while (c<n && b[c+1]<a[i]) ++c;
        r[i]=c;
    }

    g[0][0]=1;
    for (int i=1; i<=n; ++i)
        for (int j=0; j<=i; ++j) g[i][j]=(g[i-1][j]+(j ? 1ll*(r[i]-j+1)*g[i-1][j-1]%mod : 0ll))%mod;
    for (int i=0; i<=n; ++i) f[i]=g[n][i]*fac[n-i]%mod;
    for (int i=n; i>=K; --i)
    {
        ans[i]=f[i];
        for (int j=i+1; j<=n; ++j) ans[i]=(ans[i]-ans[j]*C(j,i)%mod+mod)%mod;
    }
    write(ans[K]);
    IO::flush();
    return 0;
}

Guess you like

Origin www.cnblogs.com/G-hsm/p/11374121.html