zoukankan      html  css  js  c++  java
  • bzoj 2839 集合计数 容斥广义容斥

    LINK:集合计数

    容斥简单题 却引出我对广义容斥的深思。

    一直以来我都不理解广义容斥是为什么 在什么情况下使用。

    给一张图:

    avatar

    这张图想要表达的意思就是这道题目的意思 而求的东西也和题目一致。

    特点:求出某个集合恰好为k的个数。

    转换:求出集合>=k的个数或者<=k的个数 从而使用广义容斥容斥出来答案。

    关于>=k个数 如上图可见 又很多重复的地方 而广义容斥也是在这么多重复的地方使用的 而并非严格>=k的个数。

    换个说法 >=k的方案数 可能有一些存在重复 但是其特点是>=k 关于这个特点可以利用二进制的子集关系表现出来。

    如 S1,S2都是恰好为k的 他们都能生成S3这个==k+1的集合 此时可以发现 S3被S1生成一次 被S2生成一次。所以所谓的>=k的方案数其中有一部分是子集的互相生成重复。

    广义容斥就是利用这一点来计算的。

    转到题目 不难发现 符合上面定义的>=k方案数为 (C(n,k)(2^{2^{n-k}}-1))

    套广义容斥的式子即可求出答案 值得注意的是 (2^{n-k})可以由欧拉定理%(mod-1).

    这道题还是一个简单容斥的类型。

    可以发现所有的>=k的方案数为 (C(n,k)(2^{2^{n-k}}-1))

    此时讨论 关于选出的k个子集固定时 此时生成的方案除掉这k个交集可能还存在其他交集 -1个交集+2个交集-...

    这样套简单容斥的式子也行。值得注意的是这个讨论实在k个子集固定时的讨论。

    广义容斥 code:

    const ll MAXN=1000010,N=17;
    ll n,k;
    ll fac[MAXN],inv[MAXN];
    inline ll ksm(ll b,ll p,ll pp)
    {
    	ll cnt=1;
    	while(p)
    	{
    		if(p&1)cnt=cnt*b%pp;
    		b=b*b%pp;p=p>>1;
    	}
    	return cnt;
    }
    inline ll C(ll a,ll b){return a<b?0:fac[a]*inv[b]%mod*inv[a-b]%mod;}
    signed main()
    {
    	freopen("1.in","r",stdin);
    	get(n);get(k);fac[0]=1;
    	rep(1,n,i)fac[i]=fac[i-1]*i%mod;
    	inv[n]=ksm(fac[n],mod-2,mod);
    	fep(n-1,0,i)inv[i]=inv[i+1]*(i+1)%mod;
    	ll ans=0;
    	rep(k,n,i)
    	{
    		ans=(ans+(((i-k)&1)?-1:1)*(C(n,i)*(ksm(2,ksm(2,n-i,mod-1),mod)-1))%mod*C(i,k))%mod;
    	}
    	putl((ans+mod)%mod);
    	return 0;
    }
    
  • 相关阅读:
    用 ArcMap 发布 ArcGIS Server FeatureServer Feature Access 服务 PostgreSQL 版本
    ArcMap 发布 ArcGIS Server OGC(WMSServer,MapServer)服务
    ArcScene 创建三维模型数据
    ArcMap 导入自定义样式Symbols
    ArcMap 导入 CGCS2000 线段数据
    ArcMap 导入 CGCS2000 点坐标数据
    ArcGis Server manager 忘记用户名和密码
    The view or its master was not found or no view engine supports the searched locations
    python小记(3)操作文件
    pytest(2) pytest与unittest的区别
  • 原文地址:https://www.cnblogs.com/chdy/p/12797898.html
Copyright © 2011-2022 走看看