【BZOJ4671】 异或图
Description
Input
Output
Sample Input
1
1
0
Sample Output
HINT
Solution
这道题的出处是去年我们省的省队集训。
回想起去年省队集训的时候,非正式选手的我看到这道题和这道题题解时的一脸懵逼。
“为什么是2^全零行个数次方啊?”
“斯特林数是啥子啊?”
“贝尔数又是啥子啊?”
“这题为什么我看了题解还是不知道怎么做啊?”
“为什么标程的代码这么短啊?”
“……”
时隔了整整一年,重新拿到这道题,感慨颇多。
首先,连通的条件并不好算,我们考虑不连通的情况。
我们先枚举一个划分,表示不同的划分里的点一定在不同的连通块,但在同一个划分里的点不一定在同一个连通块。也就是说所有连接两个不同划分的边都必须为0。这个的方案数可以用高斯消元算,答案会等于2^s-基的个数。
然后我们再考虑每种方案都被重复算了多少遍。一个划分集合如果是另一个划分集合的子集的话那么它被重复算的系数是斯特林数,我们可以暴力把这个容斥系数算出来(如果打表打出来会发现其实是阶乘)。
复杂度是贝尔数的第N项*高斯消元的。
代码的确很短。
Code
#include <cstdio>
#include <bitset>
#include <cstring>
#define R register
typedef long long ll;
char str[];
int s, n, id[][], len;
std::bitset<> b[], t, c[];
int col[];
ll pw[], ans, f[], S[][];
void dfs(R int x, R int cl)
{
if (x > n)
{
R int cnt = , ji = ;
for (R int i = ; i <= n; ++i)
for (R int j = i + ; j <= n; ++j)
if (col[i] != col[j]) t.set(cnt), ++cnt;
else t.reset(cnt), ++cnt;
for (R int i = ; i <= s; ++i)
{
c[i] = b[i] & t;
// for (R int j = 0; j < len; ++j) printf("%d", c[i][j] == 1); puts("");
}
for (R int i = , bs = ; i <= s && bs < len; )
{
if (c[i][bs] == )
{
for (R int j = i + ; j <= s; ++j)
if (c[j][bs])
{
std::swap(c[i], c[j]);
break;
}
}
if (c[i][bs] == ) {++bs; continue;}
++ji;
for (R int j = i + ; j <= s; ++j)
if (c[j][bs])
c[j] ^= c[i];
++i; ++bs;
}
// for (R int i = 1; i <= n; ++i) printf("%d ", col[i]); puts("");
// printf("base %d pw %lld\n", ji, f[cl] * pw[s - ji]);
ans += f[cl] * pw[s - ji];
return ;
}
for (R int i = ; i <= cl; ++i)
{
col[x] = i;
dfs(x + , cl);
}
col[x] = cl + ;
dfs(x + , cl + );
}
int main()
{
scanf("%d", &s);
pw[] = ;
for (R int i = ; i <= s; ++i)
{
scanf("%s", str); pw[i] = pw[i - ] * ;
len = strlen(str);
for (n = ; n <= ; ++n) if (n * (n - ) == len * ) break;
for (R int j = ; j < len; ++j) b[i][j] = (str[j] == '');
}
// for (R int i = 1; i <= s; ++i) {for (R int j = 0; j < len; ++j) printf("%d", b[i][j] == 1); puts("");}
S[][] = ;
for (R int i = ; i <= n; ++i)
{
S[i][] = ;
for (R int j = ; j <= i; ++j)
S[i][j] = S[i - ][j - ] + j * S[i - ][j];
}
f[] = ;
for (R int i = ; i <= n; ++i)
{
for (R int j = i - ; j; --j)
f[i] -= S[i][j] * f[j];
// printf("%lld\n", f[i]);
}
R int cnt = ;
for (R int i = ; i <= n; ++i)
for (R int j = i + ; j <= n; ++j)
id[i][j] = id[j][i] = cnt++;
dfs(, );
printf("%lld\n", ans);
return ;
}
/*
3
111
111
111
*/
【BZOJ4671】 异或图的更多相关文章
- bzoj4671: 异或图——斯特林反演
[BZOJ4671]异或图 - xjr01 - 博客园 考虑先算一些限制少的情况 gi表示把n个点的图,划分成i个连通块的方案数 连通块之间不连通很好处理(怎么处理看下边),但是内部必须连通,就很难办 ...
- bzoj4671: 异或图
bzoj4671: 异或图 Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 ( ...
- bzoj4671 异或图(斯特林反演,线性基)
bzoj4671 异或图(斯特林反演,线性基) 祭奠天国的bzoj. 题解时间 首先考虑类似于容斥的东西. 设 $ f_{ i } $ 为至少有 $ i $ 个连通块的方案数, $ g_{ i } $ ...
- BZOJ4671异或图
题目描述 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 (u, v) 在 G 中, 否则这条边不在 ...
- BZOJ4671 异或图(容斥+线性基)
题意 定义两个结点数相同的图 \(G_1\) 与图 \(G_2\) 的异或为一个新的图 \(G\) ,其中如果 \((u, v)\) 在 \(G_1\) 与 \(G_2\) 中的出现次数之和为 \(1 ...
- BZOJ4671 异或图 斯特林反演+线性基
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4671 题解 半年前刚学计数的时候对这道题怀着深深的景仰,现在终于可以来做这道题了. 类似于一般 ...
- 【BZOJ4671】异或图(斯特林反演)
[BZOJ4671]异或图(斯特林反演) 题面 BZOJ Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出 ...
- 【XSY2701】异或图 线性基 容斥原理
题目描述 定义两个图\(G_1\)与\(G_2\)的异或图为一个图\(G\),其中图\(G\)的每条边在\(G_1\)与\(G_2\)中出现次数和为\(1\). 给你\(m\)个图,问你这\(m\)个 ...
- BZOJ 4671 异或图 | 线性基 容斥 DFS
题面 Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 (u, v) 在 G 中 ...
- 【bzoj4671】异或图(容斥+斯特林反演+线性基)
传送门 题意: 给出\(s,s\leq 60\)张图,每张图都有\(n,n\leq 10\)个点. 现在问有多少个图的子集,满足这些图的边"异或"起来后,这张图为连通图. 思路: ...
随机推荐
- kubernetes dashboard访问用户添加权限控制
前面我们在kubernetes dashboard 升级之路一文中成功的将Dashboard升级到最新版本了,增加了身份认证功能,之前为了方便增加了一个admin用户,然后授予了cluster-adm ...
- centos服务器之间相互挂载(samba)
前提:假设A服务器ip为:192.168.1.101 ,B服务器ip为:192.168.1.102现在要求把A服务器的/mnt/test 路径下的文件夹 共享到B服务器的/home/ceshi 下. ...
- Docker——手动创建镜像
启动一个进入容器: 在阿里云镜像下载一个nginx: 退出容器: 查看 : docker ps -a oldboyedu是用户名 就像githua一样也有用户名 v1是别名 在创建个容器使用刚才创建的 ...
- spring-cloud 学习二 服务发现
注册中心服务发现的例子 添加module pom文件如下 <?xml version="1.0" encoding="UTF-8"?> <pr ...
- SNI功能在NetScaler上的实现
SNI功能在NetScaler上的实现 来源 https://raynorli.com/2018/09/11/sni-on-netscaler/ 现网中经常是一台主机上运行多个Web站点,如果启用了 ...
- layer插件loading快速应用示例
1.页面引用<link rel="stylesheet" href="../Js/layer/skin/layer.css" /><scri ...
- 爬虫中什么是requests
print(response.text) #响应的信息 print(response.headers) #获取响应头 print(response.status_code) #响应状态码 print( ...
- Nginx----请求分发中心
Nginx请求分发中心,需要明确几个基本问题,什么是请求,分发中心是什么,为什么需要分发中心. 什么是请求? Niginx是一款高性能的HTTP服务器,这里的请求当然是指接收客户端发送的http协议请 ...
- Linq表达树(固定参数)
这篇博客只能用来批判因为我刚刚学习linq对它了解只有简单的linq to sql 的语句所以来写这个博客只能说是班门弄斧了,看的下去的话就坚持看吧. 在网上看了别人的文章目前水平有限借鉴别人的思想吧 ...
- PHP-MYSQL中文乱码问题.
从MySQL 4.1开始引入多语言的支持,但是用PHP插入的中文会出现乱码.无论用什么编码也不行. 解决这个问题其实很简单. 1.在建表的时候设置编码类型为gb2312_chinese_ci. 2.在 ...