[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. Android 手机连不上电脑

    [个人经验] 给大家分享一下,最近Android开发中一个坑. 在Android开发中,有时会需要自己开发服务端,就需要连接自己的电脑. ①首先,我们得知道我们电脑的ip地址是多少: 开始菜单---- ...

  2. git 的 origin 的含义

    我们从progit 一书中可以看到: 远程仓库名字 “origin” 与分支名字 “master” 一样,在 Git 中并没有任何特别的含义一样. 同时“master”是当你运行git init时默认 ...

  3. Linux中输入输出重定向的问题

      Linux 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示.一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器. 输出重定向:命令的输出不 ...

  4. Kafka 安装配置 windows 下

    Kafka 安装配置 windows 下 标签(空格分隔): Kafka Kafka 内核部分需要安装jdk, zookeeper. 安装JDK 安装JDK就不需要讲解了,安装完配置下JAVA_HOM ...

  5. Java 集合系列(一)

    Java集合系列文章将以思维导图为主要形式来展示知识点,让零碎的知识形成体系. 这篇文章主要介绍的是[Java 集合的基本知识],即Java 集合简介. 毕业出来一直使用 PHP 进行开发,对于大学所 ...

  6. Windows server 2012 R2 部署WSUS补丁服务

    一.WSUS 安装要求 1.硬件要求: 对于多达 13000 个客户端的服务器,建议使用以下硬件:* 4 Core E5-2609 2.1GHz 的处理器* 8 GB 的 RAM 2.软件要求: 要使 ...

  7. 【Python 20】BMR计算器4.0(异常处理)

    1.案例描述 基础代谢率(BMR):我们安静状态下(通常为静卧状态)消耗的最低热量,人的其他活动都建立在这个基础上. 计算公式: BMR(男) = (13.7*体重kg)+(5.0*身高cm)-(6. ...

  8. PSQLException: FATAL: no pg_hba.conf entry for host "127.0.0.1", user "ambari", database "ambari", SSL off

    On your Postgres server, you will need to update your pg_hba.conf file to allow access for the ambar ...

  9. ZooKeeper Dynamic Reconfiguration (dynamicConfigFile) ZooKeeper动态配置

    有人翻译的地址:https://www.cnblogs.com/dupang/p/5649843.html ZooKeeper Dynamic Reconfiguration Overview Cha ...

  10. SQL MAX() 函数

    MAX() 函数 MAX 函数返回一列中的最大值.NULL 值不包括在计算中. SQL MAX() 语法 SELECT MAX(column_name) FROM table_name 注释:MIN ...