bzoj 3622: 已经没有什么好害怕的了
3622: 已经没有什么好害怕的了
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1088 Solved: 509
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
4 2
5 35 15 45
40 20 10 30
5 35 15 45
40 20 10 30
Sample Output
4
HINT
输入的2*n个数字保证全不相同。
还有输入应该是第二行是糖果,第三行是药片
要用到二项式反演
#include<iostream> #include<cstdio> #include<algorithm> #define maxn 2010 #define mod 1000000009 using namespace std; int n,m,a[maxn],b[maxn],nxt[maxn]; long long f[maxn][maxn],dp[maxn],c[maxn][maxn],fac[maxn]; void prepare(){ for(int i=0;i<=n;i++)c[i][0]=1; for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod; fac[1]=1; for(int i=2;i<=n;i++)fac[i]=fac[i-1]*i%mod; } int main(){ scanf("%d%d",&n,&m);m=(m+n)/2; for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=n;i++)scanf("%d",&b[i]); sort(a+1,a+n+1);sort(b+1,b+n+1); for(int i=1,j=1;i<=n;i++){ while(j<=n&&b[j]<a[i])j++; nxt[i]=j-1; } prepare(); 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]+f[i-1][j-1]*max(nxt[i]-j+1,0))%mod; for(int i=n;i>=m;i--){ dp[i]=f[n][i]*fac[n-i]%mod; for(int j=i+1;j<=n;j++) dp[i]=((dp[i]-dp[j]*c[j][i]%mod)%mod+mod)%mod; } cout<<dp[m]<<endl; return 0; }