bzoj 4671 异或图 —— 容斥+斯特林反演+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671
首先,考虑容斥,就是设 \( t[i] \) 表示至少有 \( i \) 个连通块的方案数;
我们希望得到恰好有一个连通块的方案数,但这里不能直接 \( + t[1] - t[2] + t[3] - t[4] ... \),因为每个“恰好 \( i \) 个连通块”的情况并不是在各种 \( t[j] ( j<=i ) \) 中只被算了一次,而是因为标号,被算了 \( S(i,j) \) 次;
所以希望得到一个容斥系数 \( f[i] \) ,若设 \( g[m] \) 表示恰好 \( m \) 个连通块的情况,则令 \( g[m] = \sum\limits_{i=1}^{m} S(m,i) * f[i] * t[i] \)
又因为 \( ans = g[1] \),所以干脆令 \( f[i] \) 满足 \( [m=1] = \sum\limits_{i=1}^{m} S(m,i) * f[i] \),代入 \( t[i] \),算出的就是 \( g[1] \) ,即答案;
可以斯特林反演,于是 \( f[m] = \sum\limits_{i=1}^{m} s(m,i) * (-1)^{m-i} * [i=1] \),这里的 \( s(m,i) \) 是第一类斯特林数;
于是 \( f[m] = (m-1)! * (-1)^{m-1} \)
接下来问题就是求 \( t[i] \)
\( dfs \) 枚举集合划分,复杂度是 \( Bell[n] \) 的,可以接受;
枚举了集合划分后,这些集合之间一定不能有边,这与每张图的连边情况构成了一组线性方程组;
找出线性基有 \( cnt \) 个,那么 \( s-cnt \) 张图的使用是不受限制的,换句话说,即使随便使用,构成一种情况,也可以通过线性基的那些图调整成集合间没有连边的情况;
所以 \( t[集合数] \) 加上 \( 2^{s-cnt} \)
不用数组而用一个 long long 整数,再预处理2的整数次幂,可以把时间优化到bzoj上的一般水平囧。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int s,n,m,cnt,id[][],col[],jc[],t[];
bool sid[][],vis[];
ll f[],a[],bin[];
char ch[];
ll pw(ll a,int b)
{
ll ret=;
for(;b;b>>=,a=a*a)if(b&)ret=ret*a;
return ret;
}
void add(int x)
{
cnt++; a[cnt]=;
for(int i=;i<=s;i++)
if(sid[i][x])a[cnt]|=bin[i-];//G[i]->ed[x]
}
int cal()
{
int num=;
memset(vis,,sizeof vis);
for(int i=;i<=cnt;i++)
for(int j=;j<=s;j++)
{
if(!(bin[j-]&a[i]))continue;
if(vis[j])a[i]^=a[t[j]];
else {num++,vis[j]=,t[j]=i; break;}//
}
return s-num;
}
void dfs(int x,int cr)
{
if(x==n+)
{
cnt=;
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(col[i]!=col[j])add(id[i][j]);
f[cr]+=pw(,cal());
return;
}
for(int i=;i<=cr;i++)col[x]=i,dfs(x+,cr),col[x]=;
col[x]=cr+; dfs(x+,cr+);
col[x]=;
}
void init()
{
jc[]=;
for(int i=;i<=n;i++)jc[i]=jc[i-]*i;
bin[]=;
for(int i=;i<=s;i++)bin[i]=bin[i-]+bin[i-];
}
int main()
{
scanf("%d",&s);
for(int i=;i<=s;i++)
{
scanf("%s",ch+); m=strlen(ch+);
for(int j=;j<=m;j++)sid[i][j]=ch[j]-'';
}
while(n*(n-)/<m)n++;
for(int i=,tmp=;i<=n;i++)
for(int j=i+;j<=n;j++)id[i][j]=id[j][i]=++tmp;//id[j][i]
init();
dfs(,);
ll ans=;
for(int i=;i<=n;i++)
ans+=(i&?:-)*jc[i-]*f[i];
printf("%lld\n",ans);
return ;
}
bzoj 4671 异或图 —— 容斥+斯特林反演+线性基的更多相关文章
- bzoj 4671 异或图——容斥+斯特林反演+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 考虑计算不是连通图的方案,乘上容斥系数来进行容斥. 可以枚举子集划分(复杂度是O(Be ...
- 【bzoj4671】异或图(容斥+斯特林反演+线性基)
传送门 题意: 给出\(s,s\leq 60\)张图,每张图都有\(n,n\leq 10\)个点. 现在问有多少个图的子集,满足这些图的边"异或"起来后,这张图为连通图. 思路: ...
- BZOJ4671 异或图 斯特林反演+线性基
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4671 题解 半年前刚学计数的时候对这道题怀着深深的景仰,现在终于可以来做这道题了. 类似于一般 ...
- BZOJ 4671 异或图 | 线性基 容斥 DFS
题面 Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 (u, v) 在 G 中 ...
- BZOJ4671 异或图(容斥+线性基)
题意 定义两个结点数相同的图 \(G_1\) 与图 \(G_2\) 的异或为一个新的图 \(G\) ,其中如果 \((u, v)\) 在 \(G_1\) 与 \(G_2\) 中的出现次数之和为 \(1 ...
- [BZOJ 4671]异或图
Description 题库链接 给定 \(s\) 个结点数相同且为 \(n\) 的图 \(G_1\sim G_s\) ,设 \(S = \{G_1, G_2,\cdots , G_s\}\) ,问 ...
- HDU 2841 容斥 或 反演
$n,m <= 1e5$ ,$i<=n$,$j<=m$,求$(i⊥j)$对数 /** @Date : 2017-09-26 23:01:05 * @FileName: HDU 284 ...
- 【题解】[HAOI2018]染色(NTT+容斥/二项式反演)
[题解][HAOI2018]染色(NTT+容斥/二项式反演) 可以直接写出式子: \[ f(x)={m \choose x}n!{(\dfrac 1 {(Sx)!})}^x(m-x)^{n-Sx}\d ...
- 【BZOJ】4671: 异或图
题解 写完之后开始TTTTTTT--懵逼 这道题我们考虑一个东西叫容斥系数啊>< 这个是什么东西呢 也就是\(\sum_{i = 1}^{m}\binom{m}{i}f_{i} = [m ...
随机推荐
- 一起学Django之Day01
创建项目 SimilarFacedeMacBook-Pro:PycharmProjects similarface$ django-admin startproject StudyDjango 创建A ...
- openwrt patch
一: 这几天使用一款电信的4G网卡,发现了一些问题,所以决定打个pitch来解决问题,顺便把patch的生成与使用学习一下 二:安装patch的管理工具quilt 1. sudo apt-get in ...
- php开启pathinfo 模式
pathinfo 模式 需要 php.ini 开启下面这个参数 cgi.fix_pathinfo=1 path_info模式:http://www.xxx.com/index.php/模块/方法 ...
- Appium python自动化测试系列之使用HTMLTestRunner生成测试报告(十三)
13.1 测试报告概述 13.1.1 测试报告的定义 在前面章节我们已经讲了自动化基础的很多东西,如果说掌握了,而且自己动手去练习了,我相信在一些初级的面试中是没任何问题的,今天我们接触的应该算是一 ...
- opensearch空查询
query子句不支持为空的查询,可以使用filter子句:filter=area="" 或者 filter=filedlen(area)=0 可以使用相关性函数实现:https ...
- ASP.NET动态网站制作(10)-- JQ(2)
前言:jq的第二节课. 内容: 1.管理选择结果: (1)获取元素个数:$("img").size():获取页面中所有“img”个数: (2)提取元素:$("img[ ...
- python读写数据篇
一.读写数据1.读数据 #使用open打开文件后一定要记得调用文件对象的close()方法.比如可以用try/finally语句来确保最后能关闭文件.file_object = open('thefi ...
- 九度OJ 1161:Repeater(复制器) (递归)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1449 解决:508 题目描述: Harmony is indispensible in our daily life and no one ...
- 九度OJ 1156:谁是你的潜在朋友 (并查集)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5802 解决:2593 题目描述: "臭味相投"--这是我们描述朋友时喜欢用的词汇.两个人是朋友通常意味着他们存在着许多 ...
- 我的Android进阶之旅------>如何在多个LinearLayout中添加分隔线
如果要适合于所有的Android版本,可以在多个LinearLayout放置用于显示分隔线的View.例如,放一个ImageView组件,然后将其背景设为分隔线的颜色或图像,分隔线View的定义代码如 ...