bzoj 4671 异或图——容斥+斯特林反演+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671
考虑计算不是连通图的方案,乘上容斥系数来进行容斥。
可以枚举子集划分(复杂度是O(Bell))。就是 dfs ,记录已经有了几个集合,枚举当前元素放在哪个集合里(给它标一个 id )或者当前元素自己开一个集合。
然后就有了限制:不同点集之间不能有边。本来想限制同一点集必须是连通的,但不好限制,所以就不限制了,把这部分的影响算在容斥系数里。
如果限制不同点集之间不能有边,可以考虑高斯消元。有 k 条边有限制的话,就写出 k 个方程,解出自由元的个数 d ,2d 就可以加入答案。
不过线性基更好写。https://www.cnblogs.com/ljh2000-jump/p/5869991.html
在这道题里,可以算每个图的 nw 值, nw 的第 i 位是1表示第 i 条边限制不能选,而且这个图有第 i 条边;其余情况的话这个图选不选对于第 i 条边是否合法没有影响(也可以是第 i 条边没有限制,所以其合法性自然不会受到任何图选不选的影响),第 i 位上的值就是 0 。这个 nw 只要把 “有限制的边的位是1” 的那个 long long 和 “这个图有的边的位是1” 的那个 long long & 一下就行了。
然后合法的子集选取方案需要满足选中的图的 nw 异或起来是0。所以对这些 nw 求一个线性基,设线性基大小为 k 、一共 m 个图,则方案数为 2m-k ,因为不在线性基里的图可以任意选,选好它们后异或出来的结果可以通过线性基里的唯一一种选法来调成0。
这样就求出了 “至少有 i 个连通块” 的方案数 w[ i ] 。考虑怎么用它求出 “恰好有 i 个连通块” 的方案数 g[ i ] 。
设容斥系数为 f[ i ] 。统计答案的时候,有 \( ans=\sum\limits_{i=0}^{n}w[i]*f[i] \)
对于 g[ m ] 来说,在 w[ i ] 里包含了 S( m,i ) 个 g[ m ] 。所以 g[ m ] 会被加到答案里 \( \sum\limits_{i=0}^{n}S(m,i)*f[i] \) 次。
现在想要的效果是选取了合适的 f[ ] ,使得求好的 ans 里只包含了 1 个 g[ 1 ] 。
即: \( \sum\limits_{i=0}^{n}S(m,i)*f[i] = [ m=1 ] \)
设 \( h(m) = [ m=1 ] \) ,则 \( h[m]=\sum\limits_{i=0}^{n}S(m,i)*f[i] \)
因为 S( i , j ) = 0 ( j>i ) ,所以也就是 \( h[m]=\sum\limits_{i=0}^{m}S(m,i)*f[i] \)
这样就是斯特林反演的形式了。于是有 \( f[m]=\sum\limits_{i=0}^{m}(-1)^{m-i}*s(m,i)*h[i] \)
只有 i=1 时 h 的值是1,所以就是 \( f[m]=(-1)^{m-1}*(m-1)! \) (\( s(m,i)=\frac{m!}{m}=(m-1)! \))
这样就得到了容斥系数,就可以统计答案啦!
之所以这里的容斥系数不是那种 (-1)k 了,是因为那种系数适用于 “至少一个连通块” = “恰好一个连通块”+“恰好两个连通块+ ... ,而这里是:“至少一个连通块” = “恰好一个连通块 * S(1,1)”+“恰好两个连通块 * S(2,1)” + ... 。
注意到处开 long long 。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const int N=,M=,K=;
int n,m,f[K],id[K];
ll ans,bin[N],b[N],base[M];
void init()
{
scanf("%d",&m); char ch[M];
scanf("%s",ch); int len=strlen(ch);
n=(+sqrt(+*len))/; f[]=;for(int i=;i<=n;i++)f[i]=f[i-]*i;
for(int i=n;i;i--)f[i]=((i-)&?-:)*f[i-]; bin[]=;for(int i=,j=max(m,len-);i<=j;i++)bin[i]=bin[i-]<<;//max(m,len-1) for(int i=;i<len;i++)b[]|=(ch[i]=='')?bin[i]:;
for(int i=;i<=m;i++)
{
scanf("%s",ch);
for(int j=;j<len;j++)b[i]|=(ch[j]=='')?bin[j]:;
}
}
void dfs(int cr,int cnt)
{
if(cr>n)
{
ll t=;int bh=;//ll
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++,bh++)
t|=(id[i]==id[j])?:bin[bh];
int tot=;
for(int k=;k<=bh;k++)base[k]=;//<=bh
for(int i=;i<=m;i++)
{
ll nw=b[i]&t;
for(int k=;k<=bh;k++)//bh
if(nw&bin[k])
{
if(!base[k]){base[k]=nw;tot++;break;}
nw^=base[k];
}
}
ans+=bin[m-tot]*f[cnt];
return;
}
for(int i=;i<=cnt;i++)
id[cr]=i,dfs(cr+,cnt);
id[cr]=cnt+; dfs(cr+,cnt+);
}
int main()
{
init();
dfs(,);
printf("%lld\n",ans);
return ;
}
bzoj 4671 异或图——容斥+斯特林反演+线性基的更多相关文章
- bzoj 4671 异或图 —— 容斥+斯特林反演+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 首先,考虑容斥,就是设 \( t[i] \) 表示至少有 \( i \) 个连通块的方 ...
- 【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 ...
随机推荐
- 《Maven实战》第13章 版本管理
版本管理:项目整体版本的演变过程的管理,如从1.0-SNAPSHOT到1.0,再到1.1-SNAPSHOT 版本控制:借助版本控制工具追踪代码的每一个变更 13.1什么是版本管理 版本管理:项目整体版 ...
- System.load 和 System.loadLibrary详解
System.load 和 System.loadLibrary详解 1.它们都可以用来装载库文件,不论是JNI库文件还是非JNI库文件.在任何本地方法被调用之前必须先用这个两个方法之一把相应的JNI ...
- Spring @Transactional (一)
Spring @Transactional (一) 博客分类: JAVA SpringJPAJDBCUPSQL Spring事务的传播行为 在service类前加上@Transactional,声明 ...
- lucene学习-2 - 一个示例
接下来我会写一个lucene的实例.实际上在搜索引擎上随便搜索下都能找到这样的东西.不过还是写一下吧,这也是我学习的经历. package com.zhyea.doggie; import java. ...
- JSON01_资料
1. 资料网址: http://blog.csdn.net/vincent_czz/article/details/7333977 http://blog.csdn.net/huangwuyi/art ...
- 图片与路径(Path)的应用
图片的应用:软盘样式的保存按钮,笔记本样式的编辑按钮:只能用图片 路径(Path)的应用:异形轮廓(各种气泡框,普通控件无法描述):异形线条(普通控件无法描述):图片(不建议,因为展现效果不好,比如: ...
- UVA 11538 排列组合
https://vjudge.net/problem/UVA-11538#author=0 将两个不同的皇后放入N*M棋盘中,问使得二者可以相互攻击的方案个数.有可能在同一行,同一列,同一对角线,分开 ...
- mongodb停止遇到shutdownServer failed: unauthorized: this command must run from localhost when running db without auth解决方法
停止mongodb use admin db.shutdownServer(); mongos> db.shutdownServer(); assert failed : unexpected ...
- 更新增加一个门店ID字段的值
MYSQL因为不能查询一张表时同时更新一张表,同时又会有子查询大于等于一条的情况出现. 分两种情况: 1 直接JOIN 得到一张表. 然后导出做筛选 CREATE TABLE TEST SELECT ...
- is(':visible')
.end()为结束前面处理函数,返回到最初的元素 .next()为此元素的下一个元素,可以再加上.next()表示下下一个元素,以此类推 :visible 选择器选取每个当前是可见的元素.语法:$(& ...