zoukankan      html  css  js  c++  java
  • 「BZOJ2839」集合计数

    「BZOJ2839」集合计数

    题目大意:

    一个包含 (n) 个数的集合有 (2^n) 个子集,从这些子集中取出若干个集合(至少一个),使他们的交集的元素个数恰好为 (k),求方案数,答案对 (1e9+7) 取模。


    首先考虑一个很直观的思路:我们钦定 (k) 个数是他们的交集,则这样的方案数为 (inom{n}{k}) ,同时,包含这 (k) 个数的集合个数为 (2^{n-k}) ,每个集合有选与不选两个状态,但依据题意,不能够全部不选,所以这样得到的总方案数 (b_k)

    [b_k=inom{n}{k}(2^{2^{n-k}}-1) ]

    但这样求出来的结果并不是我们想要的,设这些集合真实的交集集合 (j) 个数组成的集合为 (A),钦定的 (k) 个数组成的集合为 (B) ,则当(B subseteq A) 时, 那么这个方案就会被统计一次,总共就会被统计 (inom j k) 次。

    设交集中恰好有 (k) 个元素的方案数为 (a_k),则有

    [b_k=sum_{i=k}^n inom i k a_i ]

    然后这里,我们可以利用容斥原理来推出,但更方便的是使用二项式反演,即

    [f(k)=sum_{i=k}^n inom i k g(i) iff g(k)=sum_{i=k}^n (-1)^{i-k} inom i k f(i) ]

    这个式子可以通过直接将前式代入得到。

    同样,二项式反演也还有另一种形式

    [f(n)=sum_{i=k}^n inom n i g(i) iff g(n)=sum_{i=k}^n (-1)^{n-i}inom n i f(i) ]

    证明方法类似,在此不作赘述。

    关于这道题,我们直接反演一下即可得到答案,即

    [a_k=sum_{i=k}^n (-1)^{i-k}inom i k inom n k(2^{2^{n-k}}-1) ]

    时间复杂度为 (O(n))

    ( exttt{Code:})

    #include<bits/stdc++.h>
    using namespace std;
    using ll=long long;
    const ll p=1e9+7;
    const ll maxn=1e6+5;
    ll ksm(ll a,ll b,ll p){
    	ll ans=1;
    	for(;b;b>>=1,a=1ll*a*a%p)
    		if(b&1) ans=1ll*ans*a%p;
    	return ans;
    }
    ll fac[maxn],inv[maxn];
    ll C(ll n,ll m){
    	if(n<m) return 0;
    	return 1ll*fac[n]*inv[m]%p*inv[n-m]%p;
    }
    int main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0),cout.tie(0);
    	ll n,k;
    	cin>>n>>k;
    	fac[0]=1;
    	for(ll i=1;i<=n;++i) fac[i]=1ll*fac[i-1]*i%p;
    	inv[n]=ksm(fac[n],p-2,p);
    	for(ll i=n-1;i>=0;--i) inv[i]=1ll*inv[i+1]*(i+1)%p;
    	ll ans=0;
    	for(ll i=k;i<=n;++i){
    		ans=(ans+1ll*((i-k)&1?(-1):(1))*(C(i,k)*C(n,i)%p*(ksm(2,ksm(2,n-i,p-1),p)%p-1+p))%p+p)%p;
    	}
    	cout<<ans<<'
    ';
    	return 0;
    }
    
    
  • 相关阅读:
    Java中读取.properties配置文件的通用类
    静态工厂方法中单例的延迟加载技术
    AVL树C++实现
    初探Java反射机制
    项目中一个 1 毫秒引发的问题
    用Java操作数据库Datetime数据
    【转】Linux中的EAGAIN含义
    【转】关于编译链接——gcc/g++
    《Linux多线程编程手册》读书笔记
    《Linux多线程服务端编程——使用muduo C++网络库》读书笔记
  • 原文地址:https://www.cnblogs.com/HenryHuang-Never-Settle/p/11707108.html
Copyright © 2011-2022 走看看