首页 > 其他分享 >子集反演

子集反演

时间:2023-06-04 21:37:10浏览次数:48  
标签:ch int sum 反演 子集 subseteq

什么是子集反演?

当然在此之前说明子集反演是什么 : 子集反演用于在 恰好是某个子集在这个子集中钦定/钦定这个子集 之间转换。并且子集反演有两种形式。

第一种:现在有一个集合 \(A\) ,我们定义 \(f(A)\) 表示集合 \(A\) 的答案, \(g(A)\) 表示 \(A\) 的所有子集的答案。如果有 $$g(A)=\sum_{B\subseteq A}f(B)$$

那么就可以有

\[f(A)=\sum_{B \subseteq A} (-1)^{|A|-|B|}g(B) \]

第二种(和第一种反过来):现在有一个集合 \(A\) ,我们定义 \(f(A)\) 表示集合 \(A\) 的答案,\(g(A)\) 表示 \(A\) 的所有子集的答案。如果有

\[g(A)=\sum_{A\subseteq B}f(B) \]

那么就可以有

\[f(A)=\sum_{A \subseteq B} (-1)^{|B|-|A|}g(B) \]

OK,现在我们知道什么是子集反演了,那么我们看几道例题。

[ZJOI2016]小星星

题意描述

现在给你一个 \(n\) 个节点,\(m\) 条边的图和一个 \(n\) 个节点的树。你需要给树上的每一个节点标号,满足:

  • 给节树上点标的号是一个 \(1\) 到 \(n\) 的排列
  • 标号之后的树,树上有的边,原图中也得有。

求标号方案数。

\(n \leqslant 17\) 。

思路点拨

可以发现 \(n\) 非常的小,并且是一道计数题,我们自然而然想到了状态压缩dp。我们定义状态 \(f_{i,j,S}\) 表示在 \(i\) 的子树中 \(i\) 映射的点是 \(j\) ,子树中使用了 \(S\) 这些点的映射的方案数(每一个图上的点只被使用一次)。\(S\) 是一个二进制数表示方案。转移十分简单,这里略去,我们只需要知道这样会TLE到爆就可以了。

接下来就要讲到这道题目最神的地方了,我们抛弃标号是排列的限制。你就惊人的发现,这样最终答案可以子集反演,并且我们需要用到的状态 \(f_{i,j,S}\) 表示在 \(i\) 的子树中 \(i\) 映射的点是 \(j\) ,子树中使用了 \(S\) 这些点的映射的方案数(每一个图上的点可能使用多次)是十分好求的。

考虑转移(为了方便我们抛弃 \(S\) 这一无用维):$$f_{i,j}=\prod_{k \in son} (\sum_{l=1}^{n} f_{k,l} [l \in S , 原来的图中j,l有连边])$$

这里给出一份代码(如果不理解可以看代码,很短):

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-f;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}
const int MAXN=18;
int n,m;
bool vis[MAXN][MAXN];
vector<int> e[MAXN];
int f[MAXN][MAXN];
int s[MAXN],top;
void dfs(int x,int dad){
	for(int i=1;i<=top;i++)
		f[x][s[i]]=1;
	for(int i=0;i<e[x].size();i++){
		int to=e[x][i];
		if(to==dad) continue;
		dfs(to,x);
		for(int i=1;i<=top;i++){
			int cnt=0;
			for(int j=1;j<=top;j++)
				if(vis[s[i]][s[j]])
					cnt+=f[to][s[j]];
			f[x][s[i]]*=cnt;
		}
	}
}
signed main(){
	n=read(),m=read();
	for(int i=1;i<=m;i++){
		int u=read(),v=read();
		vis[u][v]=vis[v][u]=1;
	}
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		e[u].push_back(v);
		e[v].push_back(u);
	}
	int ans=0;
	for(int i=1;i<(1<<n);i++){
		memset(f,0,sizeof(f));
		top=0;
		for(int j=0;j<n;j++)
			if(i&(1<<j))
				s[++top]=j+1;
		dfs(1,-1);
		int cnt=0;
		for(int i=1;i<=top;i++)
			cnt+=f[1][s[i]];
		if((n-top)&1) ans-=cnt;
		else ans+=cnt;
	}
	cout<<ans;
	return 0;
}

标签:ch,int,sum,反演,子集,subseteq
From: https://www.cnblogs.com/Diavolo/p/17456373.html

相关文章

  • 莫比乌斯反演
    莫比乌斯反演的题主要是构造\(F(n)\)以及\(f(n)\)例题老地方......
  • 莫比乌斯反演与最大公约数
    在数论中,有很多题目都与莫比乌斯反演有关,最典型的就是最大公约数。比如你可以见到如下常见问题。(1)已知,求为质数的的对数,或者等于1的的对数。(2)已知和,求为质数的的对数,或者等于1的的对数。(3)已知,求的对数。(4)已知和,求的对数。上面的问题其实都可以用莫比乌斯反演来解,时间复杂度都还可以......
  • 前端树形结构图treeShapeStruct,可拖拽移动,点击展开收缩,无限添加子集
    快速实现树形结构图,可拖拽移动,点击展开收缩,无限添加子集;下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12650效果图如下:  实现代码如下:#treeShapeStruct树形结构图,可拖拽移动,点击展开收缩,无限添加子集使用方法####HTML代码部分```......
  • 前端树形结构图组件 tree组件,可拖拽移动,点击展开收缩,无限添加子集
    快速实现树形结构图组件tree组件,可拖拽移动,点击展开收缩,无限添加子集;下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12650效果图如下:  实现代码如下:#treeShapeStruct树形结构图,可拖拽移动,点击展开收缩,无限添加子集使用方法####HTM......
  • 求一个数所有因子的集合的子集中满足所有数均互质的最大子集
    题意:很明显了,就是把数n的所有因子求出来,在里面挑选一些数,使这些数之间均互质,求这些的最大个数。结论:先讲结论:最大个数为数n的质因数个数加1思路:我们已知一个数的质因数,就可以把这个数表示成若干质因数的乘积,例如:12=2*2*3;其中2,3是12的质因数,表达式中2的个数是2,3的......
  • YACS 2023年5月月赛 甲组 T1 子集和(六) 题解
    YACS老师说这是道分治,但就不告诉我怎么做,我硬是用线段树卡了过去...特别解气的是把AC图片发了过去(我就是在YACS上的编程课)莫队好了说点正经的,看到是谁谁谁的倍数就能想到DP,状态设计也很水啦!设f[i]为当前考虑到的区间内,子集和%k=i的数量。新加入一个元素时,循环0~......
  • 浅谈反演
    浅谈反演二项式反演\(g_i=\sum\limits_{j=0}\binom{i}{j}f_j,f_i=\sum\limits_{j=0}(-1)^{i-j}\binom{i}{j}g_j\)还有一个的形式\(g_i=\sum\limits_{j=i}\binom{j}{i}f_j,f_i=\sum\limits_{j=i}(-1)^{i-j}\binom{j}{i}g_j\)这里只针对第一个形式,为了得到更普遍的反演,这里我......
  • 416. 分割等和子集
    给你一个只包含正整数的非空数组nums。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。输入:nums=[1,5,11,5]输出:true解释:数组可以分割成[1,5,5]和[11]。标准解法classSolution{public:boolcanPartition(vector<int>&nums)......
  • 容斥与反演技巧(三)
    Min-Max容斥简单来说,由于\(\mathbbE[\max(x,y)]\neq\max(\mathbbE[x],\mathbbE[y])\),而如果计算\(\mathbbE[\min(x,y)]\)比计算\(\mathbbE[\max(x,y)]\)容易得多,我们就通常使用min-max容斥转为计算\(\mathbbE[\min(x,y)]\)。对于上面这种\(x,y\)的情况,实际上......
  • 莫比乌斯反演常见的三个模型
    莫比乌斯反演常见模型模型1:\(\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=t]\)\[\begin{aligned}\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=t]&=\sum_{i=1}^{\lfloor\frac{n}{t}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{t}\rfloor}[gcd(i,j)=1]\\&=\sum_{i=1}^{\lfloor\f......