【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, 那么边 ( ...
随机推荐
- IDEA Mybatis plugin插件破解
破解文件: 链接:https://pan.baidu.com/s/1J7asfLc5I0RBcoYX3_yNvQ 提取码:kjxv 使用方法: C:\Users\{你的用户名}\.IntelliJId ...
- numpy计算路线距离
numpy计算路线距离 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 enumerate遍历数组 np.diff函数 numpy适用数组作为索引 标记路线上的点 \[X={X1,X ...
- bzoj 3309 反演
$n=p_1^{a_1}p_2^{a_2}…p_k^{a_k},p_i$为素数,定义$f(n)=max(a_1,a_2…,a_k)$. 给定a,b<=1e7求$\sum\limits_{i=1} ...
- css 系统自学笔记2017-12-04
一.几个常用的可以连写的样式属性 1.backgroud: 背景连写:没有先后顺序,都是可选的. 2.font字体属性连写: font: 二.元素分类 块级元素:div p h1~h6 ul li o ...
- 使用JavaScript 修改浏览器 URL 地址栏
现在的浏览器里,有一个十分有趣的功能,你可以在不刷新页面的情况下修改浏览器URL;在浏览过程中.你可以将浏览历史储存起来,当你在浏览器点击后退按钮的时候,你可以冲浏览历史上获得回退的信息,这听起来并不 ...
- [转]天才计算机程序员 -- fabrice bellard
这位老兄就是用javascript写linux的那位,他的主页是:http://bellard.org/ 上面有他的几个作品,包括qemu,ffmpeg,tcc等. 这个世界从来不缺天才,只缺乏利用天 ...
- JVM性能调优监控工具详解
现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 .... ...
- 使用win10 hyper-v安装linux系统
1.控制面板---程序---启动或关闭windows功能---启动hyper-v管理器---重启 2.配置网络 因为公司内网通过ip验证,而通过桥接的方式,虚拟机就相当于物理机所在的网络中的一台真实主 ...
- Python文件操作-文件的增删改查
需求:对文件进行增删改查 由于时间原因,本次代码没有增加任何注释,如有疑问,请联系编辑者:闫龙 其实我也是醉了,看着这些个代码,我脑袋也特么大了,没办法,大神说了,不让用新知识,只可以使用学过的,所以 ...
- J - Clairewd’s message HDU - 4300(扩展kmp)
题目链接:https://cn.vjudge.net/contest/276379#problem/J 感觉讲的很好的一篇博客:https://subetter.com/articles/extend ...