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

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

这题目固然是极阴间的

如果有重复数字,那便是我无法做出来的

可是没有​🙃,所以可以考虑一些非常常规的想法

是的,就是广义容斥

是,但又不全是

解得糖果比药片多的对数为\(x=\frac{k+n}{2}\)

我们设\(f_{i,j}\)为前\(i\)个数中有\(j\)对中糖果大于药片

但是这样的\(dp\)是无后效性的,所以我们考虑先对\(a,b\)排序

重定义\(f_{i,j}\)为前\(i\)个数中已经钦定\(j\)个糖果大于药片,而其它的还未决定

这样就可以进行转移了!

\(f_{i,j}\rightarrow f_{i+1,j}/(i+1-j)*f_{i,j}\rightarrow f_{i+1,j+1}\)

答案即为

\[\sum_{i=x}^n{i\choose x}(-1)^{x-i}f_{n,i}(n-i)! \]

#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
	T t=0;
	char k;
	bool vis=0;
	do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
	while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
	return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
# define ll long long
# define mod 1000000009
int s,k,a[2005],b[2005],f[2005][2005];
ll fac[2005],inv[2005];
ll C(int x,int y){return fac[x]*inv[y]%mod*inv[x-y]%mod;}
ll ret(int k){
	ll t=0;
	for(int i=k;i<=s;++i)
		t=(t+C(i,k)*f[s][i]*(i-k&1?-1:1)%mod*fac[s-i])%mod;
	return t;
}
int main(){
	s=read;k=read;
	if(s-k&1)return puts("0"),0;
	fac[0]=inv[0]=inv[1]=fac[1]=1;
	for(int i=1;i<=s;++i)a[i]=read;
	for(int i=2;i<=s;++i)fac[i]=fac[i-1]*i%mod,inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	for(int i=1;i<=s;++i)b[i]=read,inv[i]=inv[i-1]*inv[i]%mod;
	sort(a+1,a+s+1);sort(b+1,b+s+1);
	f[0][0]=1;
	for(int i=1;i<=s;++i){
		int w=lower_bound(b+1,b+s+1,a[i])-b-1;
		for(int j=0;j<w;++j)
			f[i][j+1]=(f[i][j+1]+1ll*(w-j)*f[i-1][j])%mod;
		for(int j=0;j<=w;++j)
			f[i][j]=(f[i][j]+f[i-1][j])%mod;
	}printf("%lld",(ret(s+k>>1)+mod)%mod);
	return 0;
}
posted @ 2021-08-05 22:08  ファイナル  阅读(32)  评论(0)    收藏  举报