【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\)个点. 现在问有多少个图的子集,满足这些图的边"异或"起来后,这张图为连通图. 思路: ...
随机推荐
- 并不对劲的复健训练-p3674
题目大意 给出序列$ a_1,...,a_n $ ( $ n\leq10^5,a\leq 10^5 $ ),有\(m\) ( \(m\leq 10^5\))个以下三类询问: (1)给出\(l,r,k\ ...
- linux常用的bash指令
文本处理 awk sed grep sort uniq cat cut echo fmt tr nl egrep fgrep wc 进程监视 ps top htop atop lsof 网络 nmap ...
- “007~ASP 0104~不允许操作”错误的解决方法(图解)
今天测试一个Z-Blog程序的上传文件时发现总提示“ 007~ASP 0104~不允许操作 ”的错误,经过度度上各位朋友的帮忙,终于找到解决方法. 这是windows2003 server对上传文件的 ...
- UVA10603Fill题解--BFS
题目链接 https://cn.vjudge.net/problem/UVA-10603 分析 经典的倒水问题,直接BFS. 对于喜闻乐见的状态判重,一开始想来个哈希函数把一个三元组映射成一个数,后面 ...
- Laravel save部分字段失效的bug问题解决
问题描述:今天在编写api的更新部分,发现有部分字段怎么更新都更新不上去. 问题排查: 经过多次测试,发现每次提交只能更新部分字段,字段分别为:id,user_id,device_room_id,na ...
- Extjs中,Vo对象中的属性无法在data中获取的解决方法
store.getById(data.data.id).raw.redpackid
- Java高并发程序设计学习笔记(六):JDK并发包(线程池的基本使用、ForkJoin)
转自:https://blog.csdn.net/dataiyangu/article/details/86573222 1. 线程池的基本使用1.1. 为什么需要线程池1.2. JDK为我们提供了哪 ...
- python WordCloud 实现词云
简单示例 from matplotlib import pyplot as plt from wordcloud import WordCloud filename = "text.txt& ...
- MySQL数据库笔记四:MySQL的约束
<1>概念 是一种限制,它是对表的行和列的数据做出约束,确保表中的数据的完整性和唯一性. <2>使用场景 创建表的时候,添加约束 <3>分类 1. default: ...
- 分布式消息中间件之kafka设计思想及基本介绍(一)
Kafka初探 场景->需求->解决方案->应用->原理 我该如何去设计消息中间件--借鉴/完善 场景 跨进程通信(进程间生产消费模型) 需求 基本需求 实现消息的发送和接收. ...