[BZOJ4671]异或图 - xjr01 - 博客园

考虑先算一些限制少的情况

gi表示把n个点的图,划分成i个连通块的方案数

连通块之间不连通很好处理(怎么处理看下边),但是内部必须连通,就很难办了

所以再降低条件,fi表示,把n个点的图,划分成i个"连通块",保证连通块之间不会有边相连,但是内部可以不连通的方案数

fi计算方法如下:

用Bell(n)的复杂度枚举集合划分,然后相邻集合之间不能连边,

然后考虑凑出符合这个集合划分的图有多少个,异或高斯消元,xi表示第i个图选择与否,如果必须不选,等号右边就是0,否则不管。

求自由元个数

fi和gi的关系:

就是枚举到底是有几个连通块

然后斯特林反演:

虽然往上枚举,但是式子证明思路是一样的,(-1)项的指数只要保证在所谓[n=m]时候是偶数就好了

高斯消元也可以换成线性基

每个图一个元素。每个线性基的位表示这个图这个边有没有,并且再和这次必要的边取&

要求多少个子集xor为全0

线性基之后,2^(s-sz)即可。

代码:

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
#define int long long
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int M=;
const int N=;
int n,m;
int edge[M][][];
ll f[*];
ll t[N];
int ans[M];
char s[N*N];
ll id[N];
int vis[*];
ll Guass(int n){
memset(ans,-,sizeof ans);
memset(vis,,sizeof vis);
// for(reg i=1;i<=n;++i){
// for(reg j=1;j<=m;++j){
// cout<<f[i][j]<<" ";
// }cout<<" = "<<f[i][m+1]<<endl;
// }
// cout<<endl;
int free=;
for(reg i=;i<=m;++i){
int id=;
for(reg j=;j<=n;++j){
if((!vis[j])&&(f[j]&(1LL*<<(i-)))) id=j;
}
if(!id){
++free;continue;
}
vis[i]=;
if(id!=i) swap(f[i],f[id]);
for(reg j=;j<=n;++j){
if(j==i) continue;
if(!vis[j]&&(f[j]&(1LL*<<(i-)))){
f[j]^=f[i];
}
}
}
return (1LL*<<free);
}
void dfs(int x,int sz){
if(x==n+){
//cout<<" x "<<x<<" sz "<<sz<<endl;
memset(f,,sizeof f);
int cnt=;
for(reg i=;i<=n;++i){
for(reg j=i+;j<=n;++j){
if(id[i]!=id[j]){
++cnt;
for(reg k=;k<=m;++k){
if(edge[k][i][j]) f[cnt]|=(1LL*<<(k-));
}
}
}
}
// cout<<" cnt "<<cnt<<endl;
t[sz]+=Guass(max(cnt,m));
return;
}
for(reg i=;i<=sz;++i){
id[x]=i;
dfs(x+,sz);
id[x]=;
}
id[x]=sz+;
dfs(x+,sz+);
id[x]=;
}
void calc(int l){
for(n=;n<=;++n){
if(n*(n-)/==l) break;
}
}
int main(){
rd(m);
for(reg i=;i<=m;++i){
scanf("%s",s+);
int l=strlen(s+);
if(!n) calc(l);
int t=;
for(reg j=;j<=n;++j){
for(reg k=j+;k<=n;++k){
++t;
edge[i][j][k]=edge[i][k][j]=s[t]-'';
}
}
}
dfs(,);
ll ans=,jie=;
for(reg i=;i<=n;++i){
if(i&){
ans+=jie*t[i];
}else{
ans-=jie*t[i];
}
jie*=i;
}
printf("%lld",ans);
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/2/16 21:40:44
*/

总结:

找到两个数组f,g

f范围宽松好统计,g范围严格难统计但是和答案有直接关系,

这样,只要得到f和g的关系,就可以找到答案!

异或下线性方程组的自由元个数:

先变成n*(n+1)的矩阵

然后高斯消元,如果某一个id找不到,那么一定是自由元了,计数器++

注意,每次找i和消除必须在全局位置,并且用一个vis标记表示是否还能动

最后削成的上三角矩阵,除了无解情况,剩下的一定有唯一解

bzoj4671: 异或图——斯特林反演的更多相关文章

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

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

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

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

  3. bzoj4671: 异或图

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

  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】异或图(斯特林反演)

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

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

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

  8. bzoj 4671 异或图——容斥+斯特林反演+线性基

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 考虑计算不是连通图的方案,乘上容斥系数来进行容斥. 可以枚举子集划分(复杂度是O(Be ...

  9. bzoj 4671 异或图 —— 容斥+斯特林反演+线性基

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 首先,考虑容斥,就是设 \( t[i] \) 表示至少有 \( i \) 个连通块的方 ...

随机推荐

  1. 第四篇 CSS

    在标签上设置style属性: background-color:#2459a2: height:48px: ... 编写CSS样式: 如何注释:/* 或 */ 一. 在标签的属性中编写 <!DO ...

  2. HDFS副本放置策略

    1.第一个副本放置在上传文件的DataNode上,如果是集群外提交,则随机挑选一个磁盘不太满,CPU不太忙的节点. 2.第二个副本放置在与第一个副本不同的机架上. 3.第三个副本放置在与第二个副本同机 ...

  3. MongoDB 聚合分组取第一条记录的案例及实现

    关键字:MongoDB: aggregate:forEach 今天开发同学向我们提了一个紧急的需求,从集合mt_resources_access_log中,根据字段refererDomain分组,取分 ...

  4. UITableView编辑模式大全解

    1.UITableView 的编辑模式 进入编辑模式 代码体现 // 设置 editing 属性 tableView?.editing = true // 这个设置的时候是有动画效果的 tableVi ...

  5. 从Excel中导入数据时,提示“未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序”的解决办法

    注意,64位系统,用64位的补丁文件; https://www.cnblogs.com/A2008A/articles/2438962.html 操作系统:使用的是64位的Windows Server ...

  6. Postman安装及入门教程

    安装 本文只是基于 Chrome 浏览器的扩展插件来进行的安装,并非单独应用程序. 首先,你要台电脑,其次,安装有 Chrome 浏览器,那你接着往下看吧. 1. 官网安装(别看) 打开官网,http ...

  7. Python基础之迭代器和生成器

    阅读目录 楔子 python中的for循环 可迭代协议 迭代器协议 为什么要有for循环 初识生成器 生成器函数 列表推导式和生成器表达式 本章小结 生成器相关的面试题 返回顶部 楔子 假如我现在有一 ...

  8. Javascrip 入门第三节课

    一.location对象 location.href 获取当前网页的URLlocation.search() 获取?之后的请求信息 location.href="URL" // 跳 ...

  9. C# for循环或者foreach往List中添加对象的时候前面的数据总被最后加入的覆盖

    昨天我旁边小姐姐遇到一个问题,就是在执行for循环往list添加数据的时候,前面的数据信息总是被后面的数据信息所覆盖.  这样编写就会造成这样的数据效果:(所有的数据都会被覆盖)     问题原因:对 ...

  10. 好程序员web前端分享css常用属性缩写

    好程序员web前端分享css常用属性缩写,使用缩写可以帮助减少你CSS文件的大小,更加容易阅读.css缩写的主要规则如下: 颜色 16进制的色彩值,如果每两位的值相同,可以缩写一半,例如: #0000 ...