首页 > 其他分享 >集合计数——题解

集合计数——题解

时间:2024-04-13 17:23:40浏览次数:27  
标签:int 题解 个数 计数 flag maxn ans 集合

题目

image

这篇题解的背景。。。(可以跳过,与题目无关)

说实话,有点恼,也 觉得自己有点唐,在以为自己已经理解了变量意义的情况下(实际上并没有)去推了半天错式子,甚至

我推出了他不对时还给自己否定了,昨天晚三还拉着\(9G\) 与我一块推。。。,结果上午发觉好像意义理解错了。。。抽象,

就当是一种历练了

分析

(以下所有知识点与变量与 \(oi-wiki\) 上几乎相同,各位可以去理解一下原理论)

题目让我们去选大集合里的子集组成的新集合,要求新集合的交集个数大于等于 \(k\) 个,

思路还是比较清晰的,由于一个元素个数为 \(k\) 的子集也符合答案,所以我们可以先把元素个数为 \(k\) 个的子集先取出来,

有 \(C^{k}_{n}\) 种,剩下的 \(n-k\) 个数组成的集合有 \(2^{n-k}\) 个,我们从这些集合里选子集组成我们答案,有\(2^{2^{n-k}}\) 种,因为不能

一个也不选,所以要减一,对此我们的总方案数 \(g_{i}=C^{i}_{n}*(2^{2^{n-i}}-1)\) 。

这里的选取肯定是有重复的( 类似于 {A}{ABC} 与 {ABC} 之类的 ),这里可以用容斥原理推式子,但有更简洁的方法

——二项式反演,或者可以看一下大佬的博客,反正肯定能看懂,看不懂就多看几个下午,不会有人看不懂吧,那么如何

将公式运用到题目中呢,我们现在已经知道, \(f_n\) 表示恰好使用 \(n\) 个不同元素形成特定结构的方案数,\(g_n\) 表示从 \(n\) 个

不同元素中选出 \(i \geq 0\) 个元素形成特定结构的总方案数。而我们之前已经求得这里 \(g_n\) 的个数了,而求的答案实际上就

是\(f_k\),这样完美符合二项式反演的公式条件,直接带入公式$$f_k=\sum^{n}_{i=k} (-1)^{i-k} C^{k} _{i} g_i$$

可得答案为$$f_k=\sum^{n}_{i=k} (-1)^{i-k} C^{k} _{i} C^{i} _{n} * ( 2 ^ {2 ^ {n-i}}-1)$$

solution

#include<bits/stdc++.h>
#define int long long 
const int maxn=1e7+10;
using namespace std;
int n,k,flag,jc[maxn],ny[maxn],jcny[maxn],ans;
int r=1000000007;

void pre()
{
	jc[0]=jc[1]=ny[0]=ny[1]=jcny[0]=jcny[1]=1;
	for(int i=2;i<=n;i++)
	{
		ny[i]=(r-(r/i)*ny[r%i])%r;
		jcny[i]=jcny[i-1]*ny[i]%r;
		jc[i]=jc[i-1]*i%r;
	}
}

int f(int n,int m)
{
	return jc[n]*jcny[m]%r*jcny[n-m]%r;
}

signed main()
{
	scanf("%lld%lld",&n,&k);
	pre(); 
	for(int i=n,flag=((n-k)&1)?-1:1,temp=1;i>=k;i--)
	{
		ans=(ans+flag*f(i,k)*f(n,i)%r*temp%r+r)%r;
		flag=-flag;
		temp=temp*(temp+2)%r;
	}
	printf("%lld",ans); 
	
	return 0;
}

标签:int,题解,个数,计数,flag,maxn,ans,集合
From: https://www.cnblogs.com/oceansofstars/p/18133100

相关文章

  • CF416E 题解
    前置知识:floyd题意给定一个\(n\)个点\(m\)条边的无向简单图,对于每对\((s,t),1\les<t\len\),求出有多少条边被至少一个\(s\tot\)的路径经过。\(n\le500,m\le\frac{n(n-1)}{2}\)题解首先一个很一眼的做法先floyd一遍求出\(dis(i,j)\),接着枚举\((s,......
  • 群在集合上的作用
    在上一部分中,我们由群\(G\)中某个元素\(g\)的左乘引发的单射讨论了陪集、同态等内容。现在,我们把这种左乘推广到任意的一个集合\(X\)上。给定一个群\((G,\cdot)\)和一个非空集合\(X\),如果我们能够定义一个\(G\)中元素和\(X\)中元素的运算\(\circ\)满足以下三条性质,就称群\(G\)作用......
  • [CF1954] Educational Codeforces Round 164 (Rated for Div. 2) 题解
    [CF1954]EducationalCodeforcesRound164(RatedforDiv.2)题解A.PaintingtheRibbon最优策略是染\(\lceil\dfrac{n}{m}\rceil\)个颜色,然后Bob会把剩下的都染成这个颜色voidwork(){intn,m,k,c;cin>>n>>m>>k;c=(n+m-1)/m;......
  • CF1618G Trader Problem 题解
    CF1618GTraderProblem题解题目链接:CF|洛谷提供一个在线做法。分析1我们不妨把\(a\)和\(b\)合并为一个序列,称合并后的序列为\(c\),并将其不降序排序。把玩样例后不难发现:对于一个物品序列\(c_1,c_2,\cdots,c_l\),满足\(\foralli<l,c_{i+1}-c_i\lek\)(即任意......
  • [CF1942] CodeTON Round 8 (Div. 1 + Div. 2, Rated, Prizes! A~E 题解
    [CF1942]CodeTONRound8(Div.1+Div.2,Rated,Prizes!A~E题解A.FarmerJohn'sChallenge只有两种情况,一种是单调递增,这时\(k=1\),另一种是所有数都相同,这时\(k=n\)。B.BessieandMEX首位可以确定,然后从前往后增量构造\(p\)即可。voidwork(){cin>>......
  • CF1837E Play Fixing 题解
    首先来考虑什么情况方案数为\(0\):可以确定,在某一层中,两个原本都能晋级的队伍比赛;可以确定,在某一层中,两个原本都不能晋级的队伍比赛。发现假如写出每一场比赛及其胜者,可以形成一棵树形结构,在里面打标记即可判断是否为\(0\)。我们设\(a_i\)表示第\(i\)层新加的队伍中位......
  • [题解][2022年江西省大学生程序设计竞赛] Remove and append
    题目描述给定一个包含n个整数的数组a。定义一个操作如下:从数组a中选择k个整数,将它们删除,并将它们的和追加到数组末尾。如果数组A比数组B(长度相同)字典序大,那么在A和B第一次不同的位置上,A的数字比B对应位置上的数字要大。例如,[0,1,14,0]比[0,1,5,6]字典序大,因为它们在第三......
  • C++算法题解 - 递归实现排列型枚举 - 递归法 (图文) (递归搜索树)
    题目:递归实现排列型枚举把1∼n这n个整数排成一行后随机打乱顺序,输出所有可能的次序。输入格式一个整数n。输出格式按照从小到大的顺序输出所有方案,每行1个。首先,同一行相邻两个数用一个空格隔开。其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面。数据......
  • [题解] [洛谷P7883] 平面最近点对(加强版)
    [洛谷P1429]平面最近点对(加强版)题目描述给定平面上的\(n\)个点,求其中距离最小的两个点之间的距离。输入格式第一行:\(n\),保证\(2\leqn\leq200000\)。接下来\(n\)行,每行两个实数:\(x,y\),表示一个点的横坐标和纵坐标,中间用一个空格隔开。输出格式仅一行,一个实数......
  • atcoder beginer 347 (abc347) D E 题解
     D就是二进制下,哪些位置有重合(两个1),哪些位置没有重合(1个1,1个0),剩下的都是0。xor的结果<2^60,就是小于60位(二进制下)。注意要有要求两个数需要是2^60,于是要有大小的判断,因为有的a,b会2^60,但是按照题目要求,这个情况不行。比如xor的结果,60位都是1,然后a、b各有60个1,那么需要有30个1......