【BZOJ】4671: 异或图
题解
写完之后开始TTTTTTT……懵逼
这道题我们考虑一个东西叫容斥系数啊><
这个是什么东西呢
也就是\(\sum_{i = 1}^{m}\binom{m}{i}f_{i} = [m = 1]\)
也就是说,我们求出m个系数,让这个式子只在[m = 1]的时候为1,其余时候为0
啥玩意啊怎么求啊
我们显然可以\(n^2\)的递推求出来,类似解方程
但是我们打个表就会发现是\(f_{i} = (-1)^{i - 1}(i - 1)!\)
然后我们再考虑这个式子的容斥意义,假如一个图有m个联通块,那么我们会计算有i个联通块的图(i <= m)的时候,都会把这个图算\(\binom{m}{i}\)遍,我们只要乘上容斥系数,就可以保证我们如果这个图是一个联通块的话值是1,否则是0
好的,那么我们考虑如何计算这个子问题至少有m个联通块的图有多少个
我们dfs每个点构成了不同集合的方案,如果一个点在同一集合,连边任意,不在同一集合的一定没有边
这样的话,我们把不在同一集合的一个点对(i,j)作为二进制的数位,如果某张图有(i,j)这条边,那么值为1,否则值为0
那么我们就是变成了要求,有s个数,异或起来为0的方案数
这个可以线性基,答案是\(2^{s - 线性基个数}\)
线性基求的方法有点鬼畜,但是正常的求线性基会T(猫锟是怎么卡的常数啊QAQ
我们把线性无关组存起来,每次得到一个新值和前面的所有值异或一下,如果异或后的值会变小就异或
代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
//#define ivorysi
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define mo 974711
#define MAXN 3005
#define RG register
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int64 fac[15],b[65],ans;
int S,graph[65][15][15],N,id[15],L;
char str[105];
void dfs(int u,int x) {
if(u > N) {
memset(b,0,sizeof(b));
int t = 0;
for(int k = 1 ; k <= S ; ++k) {
int64 val = 0;
int p = 0;
for(int i = 1 ; i <= N ; ++i) {
for(int j = i + 1 ; j <= N ; ++j) {
if(id[i] != id[j]) {
val |= (1LL << p) * graph[k][i][j];++p;
}
}
}
for(int i = 1 ; i <= t ; ++i) {
if((val ^ b[i]) < val) val ^= b[i];
}
if(val) b[++t] = val;
}
ans += fac[x] * (1LL << (S - t));
return;
}
for(int i = 1 ; i <= x + 1 ; ++i) {
id[u] = i;dfs(u + 1,x + (i > x));
}
}
void Solve() {
scanf("%d",&S);
scanf("%s",str + 1);
N = strlen(str + 1);
for(int i = 1 ; i <= 10 ; ++i) {
if(i * (i - 1) / 2 == N) {
N = i;
break;
}
}
for(int k = 1 ; k <= S ; ++k) {
int p = 0;
for(int i = 1 ; i <= N; ++i) {
for(int j = i + 1 ; j <= N ; ++j) {
graph[k][i][j] = str[++p] - '0';
}
}
if(k != S) scanf("%s",str + 1);
}
fac[1] = 1;
for(int i = 2 ; i <= N ; ++i) fac[i] = fac[i - 1] * (1 - i);
L = N * (N - 1) / 2;
dfs(1,0);
out(ans);putchar('\n');
//out(clock() / 1000000);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}
【BZOJ】4671: 异或图的更多相关文章
- BZOJ 4671 异或图 | 线性基 容斥 DFS
题面 Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 (u, v) 在 G 中 ...
- 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 \) 个连通块的方 ...
- [BZOJ 4671]异或图
Description 题库链接 给定 \(s\) 个结点数相同且为 \(n\) 的图 \(G_1\sim G_s\) ,设 \(S = \{G_1, G_2,\cdots , G_s\}\) ,问 ...
- 【BZOJ4671】异或图(斯特林反演)
[BZOJ4671]异或图(斯特林反演) 题面 BZOJ Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出 ...
- bzoj4671 异或图(斯特林反演,线性基)
bzoj4671 异或图(斯特林反演,线性基) 祭奠天国的bzoj. 题解时间 首先考虑类似于容斥的东西. 设 $ f_{ i } $ 为至少有 $ i $ 个连通块的方案数, $ g_{ i } $ ...
- bzoj4671: 异或图——斯特林反演
[BZOJ4671]异或图 - xjr01 - 博客园 考虑先算一些限制少的情况 gi表示把n个点的图,划分成i个连通块的方案数 连通块之间不连通很好处理(怎么处理看下边),但是内部必须连通,就很难办 ...
- 【XSY2701】异或图 线性基 容斥原理
题目描述 定义两个图\(G_1\)与\(G_2\)的异或图为一个图\(G\),其中图\(G\)的每条边在\(G_1\)与\(G_2\)中出现次数和为\(1\). 给你\(m\)个图,问你这\(m\)个 ...
- bzoj4671: 异或图
bzoj4671: 异或图 Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 ( ...
随机推荐
- python---django中权限框架设计
一:admin下的权限了解 推文:如何正确使用 Django的User Model (一)默认权限表是在自带auth模块,中permission表中 可以使用has_perm方法获取用户是否有这个权限 ...
- echarts地图扩展___自定义的svg图
echarts的自定义地图 标签引入js文件 <script type="text/javascript" src="echarts/require.js" ...
- SQL语句(二十)—— 数据库安全性
数据库安全性 1. SQL Server 配置管理器 => 网络配置 MSSQLSERVER 协议,如果应用程序和SQL Server 在同一机器上,仅使用 Shared Memory (共享 ...
- nodejs使用记录
安装 下载64or32的安装程序,狂点下一步,无脑安装.然后检查一下: npm 使用npm -v命令检查npm是否可用 然后我们就可以使用npm了,npm语法如下: npm install <M ...
- idea插件安装的通用操作
序:今天下午看到一个bug,很神奇,粘出来大家看看 看到这个异常栈,有经验的或者查到的答案都是mapper.xml中哪个的方法配置错了,应替换parameterMap为parameterType, 奇 ...
- [转载]Visual Studio支持Node.js
http://news.cnblogs.com/n/193893/ https://nodejstools.codeplex.com/ 微软发布了一个官方插件“Node.js Tools for Vi ...
- [php]php总结(2)
18.数组$arr[null] = 20; //array([]=>20)$arr[] = 20;//默认为下一个下标赋值unset()可以删除数组元素,但不会重建索引array_values( ...
- Python概念-定制自己的数据类型(包装)
包装:python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均 ...
- 从零单排Hadoop——1.搭建Hadoop开发环境
Hadoop环境准备:ubuntu 12.05.Hadoop 2.4 一.安装ssh 由于hadoop可以配置为集群运行,因此系统需要安装ssh工具保证集群中各节点可以互相访问. 获取ssh软件: s ...
- 【逆向知识】开发WinDBG扩展DLL
如何开发WinDbg扩展DLL WinDbg扩展DLL是一组导出的回调函数,用于实现用户定义的命令.以便从内存转储中提取特定的信息.扩展dll由调试器引擎加载,可以在执行用户模式或内核模式调试时提供自 ...