其他分享
首页 > 其他分享> > LG P4859 已经没有什么好害怕的了

LG P4859 已经没有什么好害怕的了

作者:互联网

Description

已经使 Madoka 有签订契约,和自己一起战斗的想法后,Mami 忽然感到自己不再是孤单一人了呢。

于是,之前的谨慎的战斗作风也消失了,在对 Charlotte 的傀儡使用终曲——Tiro Finale 后,Mami 面临着即将被 Charlotte 的本体吃掉的局面。

这时,已经多次面对过 Charlotte 的 Homura 告诉了学 OI 的你这样一个性质:Charlotte 的结界中有两种具有能量的元素,一种是“糖果”,另一种是“药片”,各有 $n$ 个。在 Charlotte 发动进攻前,“糖果”和“药片”会两两配对,若恰好糖果比药片能量大的组数比“药片”比“糖果”能量大的组数多 $k$ 组,则在这种局面下,Charlotte 的攻击会丟失,从而 Mami 仍有消灭 Charlotte 的可能。

你必须根据 Homura 告诉你的“糖果”和“药片”的能量的信息迅速告诉 Homura 这种情况的个数.

Solution

首先两数组升序排序,记$num_i$为$a_i$比$b$中多少元素大,$f_{i,j}$为从$a$中选$i$个,再从这$i$个中选$j$个,再从$b$中选择$j$个使$a_k > b_k$的方案数

$$f_{i,j}=f_{i-1,j}+f_{i-1,j-1}(num_j-j+1)$$

设$g_i$表示刚好选出$i$组满足$a_k > b_k$的方案数

$$g_i=f_{n,i}-\sum_{j=i+1}^n g_j\binom{j}{i}$$

#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
int n,k,a[2005],b[2005],num[2005];
long long f[2005][2005],fac[2005]={1},inv[2005],g[2005];
const long long mod=1e9+9;
inline int read()
{
    int f=1,w=0;
    char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
    return f*w;
}
long long ksm(long long a,long long p)
{
    long long ret=1;
    while(p)
    {
        if(p&1) (ret*=a)%=mod;
        (a*=a)%=mod,p>>=1;
    }
    return ret;
}
long long C(int x,int y)
{
    if(y>x||x<0||y<0) return 0;
    return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
int main()
{
    for(int i=1;i<=2000;i++) fac[i]=fac[i-1]*i%mod;
    inv[2000]=ksm(fac[2000],mod-2);
    for(int i=1999;~i;i--) inv[i]=inv[i+1]*(i+1)%mod;
    n=read(),k=read();
    if((n-k)&1) return puts("0"),0;
    k+=((n-k)>>1);
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=n;i++) b[i]=read();
    sort(a+1,a+n+1),sort(b+1,b+n+1);
    for(int i=1,pos=1;i<=n;i++)
    {
        while(b[pos]<a[i]&&pos<=n) ++pos;
        num[i]=pos-1;
    }
    for(int i=0;i<=n;i++) f[i][0]=1;
    for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) f[i][j]=(f[i-1][j]+1ll*f[i-1][j-1]*(num[i]-j+1)%mod)%mod;
    for(int i=n;i>=k;i--)
    {
        g[i]=f[n][i]*fac[n-i]%mod;
        for(int j=n;j>i;j--) (((g[i]-=g[j]*C(j,i)%mod)%=mod)+=mod)%=mod;
    }
    printf("%lld\n",g[k]);
    return 0;
}
已经没有什么好害怕的了

 

标签:LG,ch,Charlotte,int,P4859,害怕,long,2005,mod
来源: https://www.cnblogs.com/JDFZ-ZZ/p/14306915.html