BZOJ4671 异或图(容斥+线性基)
题意
定义两个结点数相同的图 \(G_1\) 与图 \(G_2\) 的异或为一个新的图 \(G\) ,其中如果 \((u, v)\) 在 \(G_1\) 与 \(G_2\) 中的出现次数之和为 \(1\) , 那么边 \((u, v)\) 在 \(G\) 中, 否则这条边不在 \(G\) 中.
现在给定 \(s\) 个结点数相同的图 \(G_{1...s}\) , 设 \(S = {G_1, G_2, \cdots , G_s}\) , 请问 \(S\) 有多少个子集的异或为一个连通图?
\(n \le 10, s \le 60\)
题解
原来听过这题,但一直没有想去写,又讲了一遍,就来做了下,可是还不会。。。
连通图计数的一个经典思路就是容斥。
对于这道题,我们先用贝尔数 \(bell(n)\) 的时间来枚举 \(n\) 个点的子集(联通块)划分,强制连通性 至少 是这个划分。
也就是说,不同子集的两个点之间一定没有边,相同子集的两个点则任意。
对于一个有 \(m\) 个连通块的图。令 \(f_i\) 为至少有 \(i\) 个联通块的容斥系数需要满足
\]
可以斯特林反演,也可以打表找规律得出
\]
那么问题就转化成,我们只考虑不同子集中的边。对于 \(s\) 个边集,有多少种异或方案使得异或和为 \(0\) 。
这个显然是可以利用线性基得到异或方案的,记线性基的元素个数为 \(tot\) ,由于之中的元素是线性无关的,其他的 \(2^{s - tot}\) 个集合是一定可以通过异或(或不异或)线性基里的某些元素得到 \(0\) 的。
那么方案数其实就是 \(2^{s - tot}\) 。
因为此题卡常,所以要卡一些常数才能通过此题qwq 具体可以看代码实现优化。
代码
#include <bits/stdc++.h>
#define For(i, l, r) for (register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for (register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Rep(i, r) for (register int i = (0), i##end = (int)(r); i < i##end; ++i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << (x) << endl
using namespace std;
template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, T b) { return b > a ? a = b, 1 : 0; }
inline int read() {
	int x(0), sgn(1); char ch(getchar());
	for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
	for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
	return x * sgn;
}
void File() {
#ifdef zjp_shadow
	freopen ("4671.in", "r", stdin);
	freopen ("4671.out", "w", stdout);
#endif
}
typedef long long ll;
const int N = 12, M = 62;
int Strl[N][N], id[N][N], n, s, fac[N], coef[N];
bitset<N> E[M][N]; char str[M];
ll base[M], ans; int bel[N];
pair<int, int> ins[M];
void Dfs(int u, int tot) {
	if (u > n) {
		Set(base, 0);
		int res = 0, tmp = -1;
		For (i, 1, n) For (j, i + 1, n)
			if (bel[i] != bel[j]) {
				ins[++ tmp] = make_pair(i, j);
			}
		For (i, 1, s) {
			ll now = 0;
			For (j, 0, tmp) if (E[i][ins[j].first][ins[j].second]) now |= 1ll << j;
			Fordown (j, tmp, 0) if (now >> j & 1) {
				if (base[j]) now ^= base[j];
				else { base[j] = now; ++ res; break; }
			}
		}
		ans += coef[tot] * (1ll << (s - res));
		return;
	}
	For (i, 1, tot + 1)
		bel[u] = i, Dfs(u + 1, max(tot, i));
}
int main () {
	File();
	s = read();
	scanf ("%s", str + 1);
	int len = strlen(str + 1);
	while (n * (n - 1) / 2 < len) ++ n;
	For (k, 1, s) {
		len = 0;
		For (i, 1, n) For (j, i + 1, n)
			E[k][i][j] = str[id[i][j] = ++ len] - '0';
		if (k < s) scanf ("%s", str + 1);
	}
	fac[0] = 1;
	For (i, 1, n) {
		fac[i] = 1ll * fac[i - 1] * i;
		coef[i] = (i & 1 ? 1 : -1) * fac[i - 1];
	}
	Dfs(1, 0);
	printf ("%lld\n", ans);
	return 0;
}
BZOJ4671 异或图(容斥+线性基)的更多相关文章
- BZOJ4671 异或图  斯特林反演+线性基
		题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4671 题解 半年前刚学计数的时候对这道题怀着深深的景仰,现在终于可以来做这道题了. 类似于一般 ... 
- bzoj 4671 异或图——容斥+斯特林反演+线性基
		题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 考虑计算不是连通图的方案,乘上容斥系数来进行容斥. 可以枚举子集划分(复杂度是O(Be ... 
- bzoj 4671 异或图 —— 容斥+斯特林反演+线性基
		题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 首先,考虑容斥,就是设 \( t[i] \) 表示至少有 \( i \) 个连通块的方 ... 
- bzoj4671 异或图(斯特林反演,线性基)
		bzoj4671 异或图(斯特林反演,线性基) 祭奠天国的bzoj. 题解时间 首先考虑类似于容斥的东西. 设 $ f_{ i } $ 为至少有 $ i $ 个连通块的方案数, $ g_{ i } $ ... 
- bzoj4671: 异或图
		bzoj4671: 异或图 Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 ( ... 
- bzoj4671: 异或图——斯特林反演
		[BZOJ4671]异或图 - xjr01 - 博客园 考虑先算一些限制少的情况 gi表示把n个点的图,划分成i个连通块的方案数 连通块之间不连通很好处理(怎么处理看下边),但是内部必须连通,就很难办 ... 
- BZOJ4671异或图
		题目描述 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 (u, v) 在 G 中, 否则这条边不在 ... 
- P5169 xtq的异或和(FWT+线性基)
		传送门 我咋感觉我学啥都是白学-- 首先可以参考一下这一题,从中我们可以知道只要知道两点间任意一条路径以及整个图里所有环的线性基,就可以得知这两个点之间的所有路径的异或和 然而我好像并不会求线性基能张 ... 
- bzoj 2844 albus就是要第一个出场 异或和出现次数 线性基
		题目链接 题意 给定\(n\)个数,将其所有的子集(\(2^n\)个)的异或和按升序排列.给出一个询问\(q\),问\(q\)在该序列中第一次出现位置的下标(下标从\(1\)开始). 题解 结论 记其 ... 
随机推荐
- Redis缓存用起来
			Redis缓存用起来 1. 引言 创建任务时我们需要指定分配给谁,Demo中我们使用一个下拉列表用来显示当前系统的所有用户,以供用户选择.我们每创建一个任务时都要去数据库取一次用户列表,然后绑定到用户 ... 
- Solrcloud(Solr集群)
			Solrcloud(Solr集群) Solrcloud介绍: SolrCloud(solr集群)是Solr提供的分布式搜索方案. 当你需要大规模,容错,分布式索引和检索能力时使用SolrCloud. ... 
- Python_函数的初识、函数的返回值、函数的参数
			1.函数的初识 def关键字 空格 函数名(与变量名命名规则相同):英文冒号 函数体 执行函数:函数名+() 函数是以功能为导向的. def login(): pass def register(): ... 
- 阿里云ECS服务器云监控(cloudmonitor)Go语言版本插件安装卸载与维护
			云监控Go语言版本插件安装_主机监控_用户指南_云监控-阿里云https://help.aliyun.com/document_detail/97929.html 云监控cloudmonitor 1. ... 
- MySQL之优化
			当 MySQL 单表记录数过大时,增删改查性能都会急剧下降,本文会提供一些优化参考,大家可以参考以下步骤来优化. 一. 单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻 ... 
- 1 Expression of Possiblity
			Expression of possibility Probably Perhaps There's a change(that) It's very likly(that) It's pos ... 
- picker-view 组件 的value失效问题
			首先检查是不是漏了绑定关系 组件内 组件引用 如过还不行就用下面的方法,顺序问题 在给暂时列表赋值之后再对value赋值 
- Day 5-4封装.__隐藏属性或者方法
			封装 property 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏. 在python中用双下划线开头的方式将属性隐藏起来(设置成 ... 
- 解决Jupyter notebook[import tensorflow as tf]报错
			参考: https://blog.csdn.net/caicai_zju/article/details/70245099 
- linux之nload和iftop查看网络使用情况
			操作系统: centos7 nload: yum install -y gcc yum install -y gcc-c++ yum install -y ncurses-devel yum inst ... 
