题意

定义两个结点数相同的图 \(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\) 个联通块的容斥系数需要满足

\[\sum_{i = 1}^{m} {m\brace i} f_i = [m = 1]
\]

可以斯特林反演,也可以打表找规律得出

\[f_i = (-1)^{i - 1} (i - 1)!
\]

那么问题就转化成,我们只考虑不同子集中的边。对于 \(s\) 个边集,有多少种异或方案使得异或和为 \(0\) 。

这个显然是可以利用线性基得到异或方案的,记线性基的元素个数为 \(tot\) ,由于之中的元素是线性无关的,其他的 \(2^{s - tot}\) 个集合是一定可以通过异或(或不异或)线性基里的某些元素得到 \(0\) 的。

那么方案数其实就是 \(2^{s - tot}\) 。

因为此题卡常,所以要卡一些常数才能通过此题qwq 具体可以看代码实现优化。

代码

  1. #include <bits/stdc++.h>
  2. #define For(i, l, r) for (register int i = (l), i##end = (int)(r); i <= i##end; ++i)
  3. #define Fordown(i, r, l) for (register int i = (r), i##end = (int)(l); i >= i##end; --i)
  4. #define Rep(i, r) for (register int i = (0), i##end = (int)(r); i < i##end; ++i)
  5. #define Set(a, v) memset(a, v, sizeof(a))
  6. #define Cpy(a, b) memcpy(a, b, sizeof(a))
  7. #define debug(x) cout << #x << ": " << (x) << endl
  8. using namespace std;
  9. template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
  10. template<typename T> inline bool chkmax(T &a, T b) { return b > a ? a = b, 1 : 0; }
  11. inline int read() {
  12. int x(0), sgn(1); char ch(getchar());
  13. for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
  14. for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
  15. return x * sgn;
  16. }
  17. void File() {
  18. #ifdef zjp_shadow
  19. freopen ("4671.in", "r", stdin);
  20. freopen ("4671.out", "w", stdout);
  21. #endif
  22. }
  23. typedef long long ll;
  24. const int N = 12, M = 62;
  25. int Strl[N][N], id[N][N], n, s, fac[N], coef[N];
  26. bitset<N> E[M][N]; char str[M];
  27. ll base[M], ans; int bel[N];
  28. pair<int, int> ins[M];
  29. void Dfs(int u, int tot) {
  30. if (u > n) {
  31. Set(base, 0);
  32. int res = 0, tmp = -1;
  33. For (i, 1, n) For (j, i + 1, n)
  34. if (bel[i] != bel[j]) {
  35. ins[++ tmp] = make_pair(i, j);
  36. }
  37. For (i, 1, s) {
  38. ll now = 0;
  39. For (j, 0, tmp) if (E[i][ins[j].first][ins[j].second]) now |= 1ll << j;
  40. Fordown (j, tmp, 0) if (now >> j & 1) {
  41. if (base[j]) now ^= base[j];
  42. else { base[j] = now; ++ res; break; }
  43. }
  44. }
  45. ans += coef[tot] * (1ll << (s - res));
  46. return;
  47. }
  48. For (i, 1, tot + 1)
  49. bel[u] = i, Dfs(u + 1, max(tot, i));
  50. }
  51. int main () {
  52. File();
  53. s = read();
  54. scanf ("%s", str + 1);
  55. int len = strlen(str + 1);
  56. while (n * (n - 1) / 2 < len) ++ n;
  57. For (k, 1, s) {
  58. len = 0;
  59. For (i, 1, n) For (j, i + 1, n)
  60. E[k][i][j] = str[id[i][j] = ++ len] - '0';
  61. if (k < s) scanf ("%s", str + 1);
  62. }
  63. fac[0] = 1;
  64. For (i, 1, n) {
  65. fac[i] = 1ll * fac[i - 1] * i;
  66. coef[i] = (i & 1 ? 1 : -1) * fac[i - 1];
  67. }
  68. Dfs(1, 0);
  69. printf ("%lld\n", ans);
  70. return 0;
  71. }

BZOJ4671 异或图(容斥+线性基)的更多相关文章

  1. BZOJ4671 异或图 斯特林反演+线性基

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4671 题解 半年前刚学计数的时候对这道题怀着深深的景仰,现在终于可以来做这道题了. 类似于一般 ...

  2. bzoj 4671 异或图——容斥+斯特林反演+线性基

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 考虑计算不是连通图的方案,乘上容斥系数来进行容斥. 可以枚举子集划分(复杂度是O(Be ...

  3. bzoj 4671 异或图 —— 容斥+斯特林反演+线性基

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 首先,考虑容斥,就是设 \( t[i] \) 表示至少有 \( i \) 个连通块的方 ...

  4. bzoj4671 异或图(斯特林反演,线性基)

    bzoj4671 异或图(斯特林反演,线性基) 祭奠天国的bzoj. 题解时间 首先考虑类似于容斥的东西. 设 $ f_{ i } $ 为至少有 $ i $ 个连通块的方案数, $ g_{ i } $ ...

  5. bzoj4671: 异或图

    bzoj4671: 异或图 Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 ( ...

  6. bzoj4671: 异或图——斯特林反演

    [BZOJ4671]异或图 - xjr01 - 博客园 考虑先算一些限制少的情况 gi表示把n个点的图,划分成i个连通块的方案数 连通块之间不连通很好处理(怎么处理看下边),但是内部必须连通,就很难办 ...

  7. BZOJ4671异或图

    题目描述 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 (u, v) 在 G 中, 否则这条边不在 ...

  8. P5169 xtq的异或和(FWT+线性基)

    传送门 我咋感觉我学啥都是白学-- 首先可以参考一下这一题,从中我们可以知道只要知道两点间任意一条路径以及整个图里所有环的线性基,就可以得知这两个点之间的所有路径的异或和 然而我好像并不会求线性基能张 ...

  9. bzoj 2844 albus就是要第一个出场 异或和出现次数 线性基

    题目链接 题意 给定\(n\)个数,将其所有的子集(\(2^n\)个)的异或和按升序排列.给出一个询问\(q\),问\(q\)在该序列中第一次出现位置的下标(下标从\(1\)开始). 题解 结论 记其 ...

随机推荐

  1. Java Core - Map接口

    Map:是一组映射The java.util.Map interface represents a mapping between a key and a value. The Map interfa ...

  2. Oss文件存储

    包含文件的上传下载和生成临时的url # -*- coding: utf-8 -*- import os import oss2 import configparser from Config imp ...

  3. PHP常见错误汇总

    日常开发和调试的时候,经常会遇到一些错误,光怪陆离的不知所以,所以,特此将错误汇总一下,借鉴!!! 1. 原因分析:  一般可能是该文件出现了问题,检查一下代码和格式,是否出现开始的地方出现了空格,或 ...

  4. MySQL 的两个特殊属性 unsigned与 zerofill

    1 unsigned unsigned 就是将数字类型无符号化, 例如 int 型的范围:-2^31 ~ 2^31 - 1,而unsigned int的范围:0 ~ 2^32.看起来unsigned ...

  5. 47.Majority Element I & II

    Majority Element I 描述 给定一个整型数组,找出主元素,它在数组中的出现次数严格大于数组元素个数的二分之一. You may assume that the array is non ...

  6. cpp11_thread线程

    一.进程与线程 cpu一般有m核n线程的说法,那么该cpu只能同时运行n个线程(线程中没有sleep). #include <thread> #include <mutex> ...

  7. JS --- 本地保存localStorage、sessionStorage用法总结

    JS的本地保存localStorage.sessionStorage用法总结 localStorage.sessionStorage是Html5的特性,IE7以下浏览器不支持 为什么要掌握localS ...

  8. scala flatmap、reduceByKey、groupByKey

    1.test.txt文件中存放 asd sd fd gf g dkf dfd dfml dlf dff gfl pkdfp dlofkp // 创建一个Scala版本的Spark Context va ...

  9. elasticsearch的映射

    一.简介: 映射:在创建索引时,可以预先定义字段的类型(映射类型,也就是type,一个索引可以有一个或多个类型)及相关属性. Elasticsearch会根据JSON源数据的基础类型猜测你想要的字段映 ...

  10. 关于对ProgressBar定义模板的一些总结

    在之前的博客中曾经写到了一篇关于如何定义圆形进度条的文章,今天就ProgressBar再来进行一些总结,首先来介绍一下ProgressBar的结构,ProgressBar控件的模板有两个部分,我们在定 ...