zoukankan      html  css  js  c++  java
  • BZOJ 3622: 已经没有什么好害怕的了(二项式反演)

    传送门

    解题思路

      首先将(a),(b)排序,然后可以算出(t(i)),表示(a(i))比多少个(b(i))大,根据容斥套路,设(f(k))表示恰好有(k)(a(i))(b(i))大,(g(k))表示至少有(k)个,那么(g(k)=sumlimits_{i=k}^ndbinom{i}{k}f(i))。发现这是一个二项式反演的形式,现在的问题变为如何求(g(k)),发现可以强制选(k)组,其余的任意搭配,强制选(k)组就可以(dp)了。设(dp(i)(j))表示前(i)个数,选了(j)个的方案数,因为(a)数组已经排好序,所以(dp(i)(j)=dp(i-1)(j)+dp(i-1)(j-1)*max(0,t(i)-j+1)),然后(g(k)=dp(n)(k)*(n-k)!)

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    
    using namespace std;
    const int N=2005;
    const int MOD=1e9+9;
    typedef long long LL;
    
    inline int rd(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
    	while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return f?x:-x;
    }
    inline int max(int x,int y){return x>y?x:y;}
    
    int n,k,a[N],b[N],t[N],f[N][N],fac[N],inv[N],ans;
    
    inline int fast_pow(int x,int y){
    	int ret=1;
    	for(;y;y>>=1){
    		if(y&1) ret=(LL)ret*x%MOD;
    		x=(LL)x*x%MOD;
    	}
    	return ret;
    }
    
    inline int C(int x,int y){
    	return (LL)fac[x]*inv[y]%MOD*inv[x-y]%MOD;
    }
    
    int main(){
    	n=rd(),k=rd();if((n+k)&1) return puts("0"),0;
    	k=(n+k)>>1;int now=1;fac[0]=1;
    	for(int i=1;i<=n;i++) a[i]=rd();
    	for(int i=1;i<=n;i++) b[i]=rd();
    	sort(a+1,a+1+n);sort(b+1,b+1+n);
    	for(int i=1;i<=n;i++){
    		t[i]=t[i-1];
    		while(a[i]>b[now] && now<=n) t[i]++,now++;
    	}
    	f[0][0]=1;
    	for(int i=1;i<=n;i++){
    		f[i][0]=1;
    		for(int j=1;j<=i;j++)
    			f[i][j]=(f[i-1][j]+(LL)f[i-1][j-1]*(max(0,t[i]-j+1))%MOD)%MOD;
    	}
    	for(int i=1;i<=n;i++) fac[i]=(LL)fac[i-1]*i%MOD;
    	inv[n]=fast_pow(fac[n],MOD-2);
    	for(int i=n-1;~i;i--) inv[i]=(LL)inv[i+1]*(i+1)%MOD;
    	for(int i=k;i<=n;i++){
    		if((i-k)&1) ans=(ans+(MOD-(LL)C(i,k)*f[n][i]%MOD*fac[n-i]%MOD))%MOD;
    		else ans=(ans+(LL)C(i,k)*f[n][i]%MOD*fac[n-i]%MOD)%MOD;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Python 如何隐藏属性
    Python 多态
    Python 绑定方法与非绑定方法
    Python 类的组合
    ASP.NET CS文件中输出JavaScript脚本的3种方法以及区别
    JQuery中$之选择器用法介绍
    C#语言之“string格式的日期时间字符串转为DateTime类型”的方法
    .net中response.redirect sever.execute server.transfer 三种页面跳转的方法
    safari,chrome中的window.history.go(-1) history.back()
    onbeforeunload与onunload事件
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10265701.html
Copyright © 2011-2022 走看看