Description

定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与
G2 中的出现次数之和为 1, 那么边 (u, v) 在 G 中, 否则这条边不在 G 中.
现在给定 s 个结点数相同的图 G1...s, 设 S = {G1, G2, . . . , Gs}, 请问 S 有多少个子集的异
或为一个连通图?

Input

第一行为一个整数s, 表图的个数.
接下来每一个二进制串, 第 i 行的二进制串为 gi, 其中 gi 是原图通过以下伪代码转化得
到的. 图的结点从 1 开始编号, 下面设结点数为 n.
Algorithm 1 Print a graph G = (V, E)
for i = 1 to n do
for j = i + 1 to n do
if G contains edge (i, j) then
print 1
else
print 0
end if
end for
end for
 2 ≤ n ≤ 10,1 ≤ s ≤ 60.

Output

输出一行一个整数, 表示方案数

Sample Input

3
1
1
0

Sample Output

4

HINT

Solution

这道题的出处是去年我们省的省队集训。

回想起去年省队集训的时候,非正式选手的我看到这道题和这道题题解时的一脸懵逼。

“为什么是2^全零行个数次方啊?”

“斯特林数是啥子啊?”

“贝尔数又是啥子啊?”

“这题为什么我看了题解还是不知道怎么做啊?”

“为什么标程的代码这么短啊?”

“……”

时隔了整整一年,重新拿到这道题,感慨颇多。

首先,连通的条件并不好算,我们考虑不连通的情况。

我们先枚举一个划分,表示不同的划分里的点一定在不同的连通块,但在同一个划分里的点不一定在同一个连通块。也就是说所有连接两个不同划分的边都必须为0。这个的方案数可以用高斯消元算,答案会等于2^s-基的个数。

然后我们再考虑每种方案都被重复算了多少遍。一个划分集合如果是另一个划分集合的子集的话那么它被重复算的系数是斯特林数,我们可以暴力把这个容斥系数算出来(如果打表打出来会发现其实是阶乘)。

复杂度是贝尔数的第N项*高斯消元的。

代码的确很短。

Code

  1. #include <cstdio>
  2. #include <bitset>
  3. #include <cstring>
  4. #define R register
  5. typedef long long ll;
  6. char str[];
  7. int s, n, id[][], len;
  8. std::bitset<> b[], t, c[];
  9. int col[];
  10. ll pw[], ans, f[], S[][];
  11. void dfs(R int x, R int cl)
  12. {
  13. if (x > n)
  14. {
  15. R int cnt = , ji = ;
  16. for (R int i = ; i <= n; ++i)
  17. for (R int j = i + ; j <= n; ++j)
  18. if (col[i] != col[j]) t.set(cnt), ++cnt;
  19. else t.reset(cnt), ++cnt;
  20. for (R int i = ; i <= s; ++i)
  21. {
  22. c[i] = b[i] & t;
  23. // for (R int j = 0; j < len; ++j) printf("%d", c[i][j] == 1); puts("");
  24. }
  25. for (R int i = , bs = ; i <= s && bs < len; )
  26. {
  27. if (c[i][bs] == )
  28. {
  29. for (R int j = i + ; j <= s; ++j)
  30. if (c[j][bs])
  31. {
  32. std::swap(c[i], c[j]);
  33. break;
  34. }
  35. }
  36. if (c[i][bs] == ) {++bs; continue;}
  37. ++ji;
  38. for (R int j = i + ; j <= s; ++j)
  39. if (c[j][bs])
  40. c[j] ^= c[i];
  41. ++i; ++bs;
  42. }
  43. // for (R int i = 1; i <= n; ++i) printf("%d ", col[i]); puts("");
  44. // printf("base %d pw %lld\n", ji, f[cl] * pw[s - ji]);
  45. ans += f[cl] * pw[s - ji];
  46. return ;
  47. }
  48. for (R int i = ; i <= cl; ++i)
  49. {
  50. col[x] = i;
  51. dfs(x + , cl);
  52. }
  53. col[x] = cl + ;
  54. dfs(x + , cl + );
  55. }
  56. int main()
  57. {
  58. scanf("%d", &s);
  59. pw[] = ;
  60. for (R int i = ; i <= s; ++i)
  61. {
  62. scanf("%s", str); pw[i] = pw[i - ] * ;
  63. len = strlen(str);
  64. for (n = ; n <= ; ++n) if (n * (n - ) == len * ) break;
  65. for (R int j = ; j < len; ++j) b[i][j] = (str[j] == '');
  66. }
  67. // for (R int i = 1; i <= s; ++i) {for (R int j = 0; j < len; ++j) printf("%d", b[i][j] == 1); puts("");}
  68. S[][] = ;
  69. for (R int i = ; i <= n; ++i)
  70. {
  71. S[i][] = ;
  72. for (R int j = ; j <= i; ++j)
  73. S[i][j] = S[i - ][j - ] + j * S[i - ][j];
  74. }
  75. f[] = ;
  76. for (R int i = ; i <= n; ++i)
  77. {
  78. for (R int j = i - ; j; --j)
  79. f[i] -= S[i][j] * f[j];
  80. // printf("%lld\n", f[i]);
  81. }
  82. R int cnt = ;
  83. for (R int i = ; i <= n; ++i)
  84. for (R int j = i + ; j <= n; ++j)
  85. id[i][j] = id[j][i] = cnt++;
  86. dfs(, );
  87. printf("%lld\n", ans);
  88. return ;
  89. }
  90. /*
  91. 3
  92. 111
  93. 111
  94. 111
  95. */

【BZOJ4671】 异或图的更多相关文章

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

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

  2. bzoj4671: 异或图

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

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

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

  4. BZOJ4671异或图

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

  5. BZOJ4671 异或图(容斥+线性基)

    题意 定义两个结点数相同的图 \(G_1\) 与图 \(G_2\) 的异或为一个新的图 \(G\) ,其中如果 \((u, v)\) 在 \(G_1\) 与 \(G_2\) 中的出现次数之和为 \(1 ...

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

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

  7. 【BZOJ4671】异或图(斯特林反演)

    [BZOJ4671]异或图(斯特林反演) 题面 BZOJ Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出 ...

  8. 【XSY2701】异或图 线性基 容斥原理

    题目描述 定义两个图\(G_1\)与\(G_2\)的异或图为一个图\(G\),其中图\(G\)的每条边在\(G_1\)与\(G_2\)中出现次数和为\(1\). 给你\(m\)个图,问你这\(m\)个 ...

  9. BZOJ 4671 异或图 | 线性基 容斥 DFS

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

  10. 【bzoj4671】异或图(容斥+斯特林反演+线性基)

    传送门 题意: 给出\(s,s\leq 60\)张图,每张图都有\(n,n\leq 10\)个点. 现在问有多少个图的子集,满足这些图的边"异或"起来后,这张图为连通图. 思路: ...

随机推荐

  1. python基础知识0-4

    collection 他是对字典 元组 集合 进行加工的  是计数器 无论 深 ,浅 ,赋值 拷贝 内存地址都不变 赋值也是拷贝的一种 拷贝分两类数字 字符串 另一类: 列表 字典 元组 这一类还分两 ...

  2. Graph、DFS、BFS

    Graph.java package Graph; import LinearLIst.bag.Bag; import edu.princeton.cs.algs4.In; public class ...

  3. Eclipse怎么改变@author 姓名

    1 点击windows  然后选择 点击进去选择搜索code Templates  点击选择出现下面的页面 点开comments,里面有给方法,变量 ,类等加注释设置的模板 如:点击Methods  ...

  4. wpf 模板绑定父对象

    有两种方式可以实现在模板中元素绑定到父对象 1.<ContentPresenter Margin=”{TemplateBinding Padding}”/> 2.Color=”{Bindi ...

  5. Express bodyParser中间件使用方式

    bodyParser中间件用来解析http请求体,是express默认使用的中间件之一. 1.这个模块提供以下解析器 (1) JSON body parser (2) Raw body parser ...

  6. CSS3总结三:文字(text)/字体、文本、文本装饰、多列

    Text-Decoration text-shadow text-decoration Font font font-face Text 常用Text属性 Multi-column Multi-col ...

  7. shiro权限控制配置

    shiro配置流程 web.xml中配置shiro的filter spring中配置shiro的过滤器工厂,指定对不同地址权限控制 , 传入安全管理器 配置安全管理器,传入realm,realm中定义 ...

  8. ADO.net 数据库连接new SqlConnection、Open、Close、Dispose

    今天踩了一个坑,用了一个static对象,存储了Connection,导致了并发量大时(35/s)出现单个连接的数据库请求堆积,以及并发Open导致的异常,最终使服务下线. 排查中发现有些概念不清的地 ...

  9. layui弹出层基础参数

    一.type-层类型 类型:Number  默认为0(信息框); 1(页面层),可以在页面添加HTML内容 2(iframe层) 3(加载层)加载时显示的弹出框 4(tips层) 需要绑定ID就不展示 ...

  10. 一键登录已成大势所趋,Android端操作指南来啦!

    根据极光(Aurora Mobile)发布的<2019年Q2移动互联网行业数据研究报告>,2019年第二季度,移动网民人均安装APP总量已达56款.面对如此繁多的APP,想在用户的手机中占 ...