集合计数

内存限制:128 MiB 时间限制:1000 ms 标准输入输出
 
 

题目描述

一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007。(是质数喔~)

输入格式

一行两个整数N,K

输出格式

一行为答案。

样例

样例输入

  1. 3 2

样例输出

  1. 6

数据范围与提示

样例说明

假设原集合为{A,B,C}

则满足条件的方案为:{AB,ABC},{AC,ABC},{BC,ABC},{AB},{AC},{BC}

数据说明

对于100%的数据,1≤N≤1000000;0≤K≤N;

一道很好的数论题(反正我看题解才做出来的 %%%%*ZJ   https://www.cnblogs.com/zj75211/p/8029343.html) 我有点菜,各种错误。

思路很奇妙,第一步:首先选出来C(n,k)个数,第二步:然后我们要做的就是让剩余集合交集为空。注意,我们选的剩余集合是除了C以外还选了什么(C上再加这个集合)

解释一下

例如 3 1

假设我们通过第一步选出来的数为A

而第二步我们选出来 C,B

那么我们最终选的集合为AB ,AC

再比如我们第二步选 空集,C

那么我们最终选出来的集合为 A,AC

既然如此我们需要求的就是所有满足的情况

正确性验证被我鸽了。。。。。。

然后我们要做的就是求出方案

设f[i]为当前集合至少选出i个数的方案数

设m为n-i(即剩余个数)

对于剩余n-i个数可以构成$2^{(n-i)}$个集合

而对于这些集合每个都可以进行选或不选(即$2{^{2^{(n-i)}}}$)种情况

而不能都不选(对于选了空集也是一种)

  $f[i]=C(n,i)*(2{^{2^{n-i}}}-1)$

显然我们算多了,然后我们需要容斥掉容斥系数,首先我们发现在所有f[k+1]中我们都多算了C(k+1,k)次

例如我们固定了四个数ABCD

我们在k+1中每种都多算了一次

ABC    D==ACD     B==ABD     C==BCD      A

得到对于f[k+1]:-C(k+1,k)

  同理f[k+2]:+C(k+2,k+1)*C(k+1,k)==C(k+2,k)

依次类推

得到

  1. for(ll i=k;i<=n;i++)
  2. ans=(C(i,k)*f[i]%p*((i-k)&1?-1:1)+ans)%p;

实际上就类似于多项容斥

而且这题因为N<=1000000

如果算C现算肯定不行,考虑到用多次,打表(阶乘及阶乘逆元),但求逆元带log仍然超时

所以还要线性求逆元

  1. ni[n]=meng(jie[n],p-2);
  2. for(ll i=n-1;i>=1;i--)ni[i]=ni[i+1]*(i+1)%p;

理解一下逆元实际上就是1/?

而$1/(n+1)!*(n+1)$其实就是$1/(n)! $就求出来逆元了

两个注意点

:for(ll i=1;i<=maxn;i++) ermi[i]=2*ermi[i-1]%(p-1);//2^ermi[i]%p!=2^ermi[i]%p调两节课

:for(ll i=0;i<=n;i++)又一节半课,实在是菜

:ermi[0]又二十分钟,

除了第一个是稍微有一点思维的错,别的都是低错。实不应该

首先关于为什么mod (p-1)而不是mod (p)

这其实要推出来,首先我们必须知道${2^{2^i mod p}}{!=2^{2^i}{mod p}}$

怎么办 设${2^i}==(kφ(p)+t)$,则原式就为$(2^{k*φ(p)}*2^t) {mod p}$

根据欧拉定理

$2^{φ(p)} mod p$同余于1,${2^i}==kφ(p)+t$t就等于$2^i mod φ(p)$,又φ(质数)==p-1

故%(p-1)而非%p

以下依然是本人丑陋的还带着调试的代码

  1. 1 #include<bits/stdc++.h>
  2. 2 #define ll long long
  3. 3 #define A 1100000
  4. 4 #define maxn 1000010
  5. 5 #define p 1000000007
  6. 6 using namespace std;
  7. 7 ll m,n,k,f[A],jie[A],ermi[A],ans,ni[A];
  8. 8 inline ll read()
  9. 9 {
  10. 10 ll f=1,x=0;char c=getchar();
  11. 11 while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
  12. 12 while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  13. 13 return f*x;
  14. 14 }
  15. 15 ll meng(ll x,ll k)
  16. 16 {
  17. 17 ll ans=1;
  18. 18 for(;k;k>>=1,x=x*x%p)
  19. 19 if(k&1)
  20. 20 ans=x%p*ans%p;
  21. 21 return ans;
  22. 22 }
  23. 23 ll C(ll n,ll m)
  24. 24 {
  25. 25 if(m==0) return 1;
  26. 26 if(m>n) return 0;
  27. 27 else return (jie[n]*ni[m]%p*ni[n-m])%p;
  28. 28 }
  29. 29 void init()
  30. 30 {
  31. 31 n=read(),k=read();
  32. 32 m=n-k;
  33. 33 jie[0]=1;ni[0]=1;ermi[0]=1;
  34. 34 for(ll i=1;i<=maxn;i++) ermi[i]=2*ermi[i-1]%(p-1);//2^ermi[i]%p!=2^ermi[i]%p
  35. 35 for(ll i=1;i<=n;i++) jie[i]=jie[i-1]*i%p;
  36. 36 ni[n]=meng(jie[n],p-2);
  37. 37 for(ll i=n-1;i>=1;i--)ni[i]=ni[i+1]*(i+1)%p;
  38. 38 for(ll i=0;i<=n;i++) f[i]=C(n,i)%p*(meng(2,ermi[n-i])%p-1)%p;
  39. 39 }
  40. 40 int main()
  41. 41 {
  42. 42 // freopen("test.in","r",stdin);freopen("vio.out","w",stdout);
  43. 43 ans=0;
  44. 44 init();
  45. 45 for(ll i=k;i<=n;i++)
  46. 46 ans=(C(i,k)*f[i]%p*((i-k)&1?-1:1)+ans)%p;
  47. 47 cout<<(ans%p+p)%p<<endl;
  48. 48 }

以及对拍

  1. 1 #include<bits/stdc++.h>
  2. 2 int main()
  3. 3 {
  4. 4 while(true)
  5. 5 {
  6. 6 system("./mkd"),puts("mkd runs out");
  7. 7 system("./std"),puts("std runs out");
  8. 8 system("./vio"),puts("vio runs out");
  9. 9 if(system("diff std.out vio.out")) while(true);
  10. 10 puts("");
  11. 11 }
  12. 12 return 0;
  13. 13 }

嗯,完了

bzoj2839 集合计数(容斥+组合)的更多相关文章

  1. bzoj2839: 集合计数 容斥+组合

    2839: 集合计数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 523  Solved: 287[Submit][Status][Discuss] ...

  2. BZOJ2839:集合计数(容斥,组合数学)

    Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007. ...

  3. BZOJ2839 集合计数 容斥

    题目描述(权限题qwq) 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得 它们的交集的元素个数为K,求取法的方案数,答案模100000000 ...

  4. bzoj 2839 集合计数 容斥\广义容斥

    LINK:集合计数 容斥简单题 却引出我对广义容斥的深思. 一直以来我都不理解广义容斥是为什么 在什么情况下使用. 给一张图: 这张图想要表达的意思就是这道题目的意思 而求的东西也和题目一致. 特点: ...

  5. BZOJ 3294: [Cqoi2011]放棋子 计数 + 容斥 + 组合

    比较头疼的计数题. 我们发现,放置一个棋子会使得该棋子所在的1个行和1个列都只能放同种棋子. 定义状态 $f_{i,j,k}$ 表示目前已使用了 $i$ 个行,$j$ 个列,并放置了前 $k$ 种棋子 ...

  6. bzoj2839 集合计数(容斥)

    2839: 集合计数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 883  Solved: 490[Submit][Status][Discuss] ...

  7. [BZOJ2839]:集合计数(组合数学+容斥)

    题目传送门 题目描述 .(是质数喔~) 输入格式 一行两个整数N,K. 输出格式 一行为答案. 样例 样例输入: 3 2 样例输出: 样例说明 假设原集合为{A,B,C} 则满足条件的方案为:{AB, ...

  8. BZOJ2839 : 集合计数 (广义容斥定理)

    题目 一个有 \(N\) 个 元素的集合有 \(2^N\) 个不同子集(包含空集), 现在要在这 \(2^N\) 个集合中取出若干集合(至少一个), 使得它们的交集的元素个数为 \(K\) ,求取法的 ...

  9. bzoj2839 集合计数 组合计数 容斥原理|题解

    集合计数 题目描述 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007.(是 ...

随机推荐

  1. 如何实现一个 System Services?

    <Android 系统开发做什么?>写到 Android System Services 是专注于特定功能的模块化组件,应用框架 API 所提供的功能可与系统服务通信,以访问底层硬件.An ...

  2. java面试一日一题:java中垃圾回收算法有哪些

    问题:请讲下在java中有哪些垃圾回收算法 分析:该问题主要考察对java中垃圾回收的算法以及使用场景 回答要点: 主要从以下几点去考虑, 1.GC回收算法有哪些 2.每种算法的使用场景 3.基于垃圾 ...

  3. [bug] CDH 安装 Error : No matching Packages to list

    信息 分析 我的系统是CentOS 7,而 cm 安装包是配合 redhat 6 的,应该选择 redhat 7 目录下的包 参考 https://community.cloudera.com/t5/ ...

  4. [DB] SQL 必知必会

    整体架构 数据类型 文本类:CHAR.VARCHAR(可变长度字符,多使用).TEXT.LONGTEXT(文本较大时使用) 数字类:TINYINT.INT.BIGINT.FLOAT.DOUBLE 日期 ...

  5. Linux创建RAID概述

    Linux创建RAID RAID概述 RAID(Redundant Array of Independent Disk)虚拟存储系统 RAID即独立冗余磁盘阵列,其思想是将多块独立的磁盘按不同的方式组 ...

  6. LTP--linux稳定性测试 linux性能测试 ltp压力测试 ltp-pan

    LTP--linux稳定性测试 linux性能测试 ltp压力测试 zhangzj1030关注14人评论33710人阅读2011-12-09 12:07:45   说明:在写这篇文章之前,本人也不曾了 ...

  7. 什么是FOC

    https://zhidao.baidu.com/question/354536332.html FOC简述 磁场定向控制系统(FOC)又称为矢量控制系统,他是选择电机某一旋转磁场轴作为特定的同步旋转 ...

  8. Redis SWAPDB 命令背后做了什么

    Redis SWAPDB 命令背后做了什么 目录 Redis SWAPDB 命令背后做了什么 0x00 摘要 0x01 SWAPDB 基础 1.1 命令说明 1.2 演示 0x02 预先校验 0x03 ...

  9. java 计算下面级数之和 1/3+3/5+5/7+...+97/99

    代码实例图:package judgment;/** * 计算下面级数之和 * 1/3+3/5+5/7+...+97/99; */public class Judgment { public stat ...

  10. 在react中使用redux并实现计数器案例

    React + Redux 在recat中不使用redux 时遇到的问题 在react中组件通信的数据是单向的,顶层组件可以通过props属性向下层组件传递数据,而下层组件不能向上层组件传递数据,要实 ...