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 ...
随机推荐
- Python流程控制与函数
if >>> x = int(raw_input("Please enter an integer:")) Please enter an integer:42 ...
- 阿里云centOS7.4 nginx: [emerg] "server" directive is not allowed here in /etc/nginx/vhost/xxxxxx.conf:2
里云centOS7.4配置多个站点遇到的问题nginx: [emerg] "server" directive is not allowed here in /etc/nginx/ ...
- 新东方雅思词汇---8.2、chron
新东方雅思词汇---8.2.chron 一.总结 一句话总结:时间 chronic 英 ['krɒnɪk] 美 ['krɑnɪk] adj. 慢性的:长期的:习惯性的 n. (Chronic)人名 ...
- Java 子类实例化对象的过程
子类实例化是否会实例化父类? 不会.父类在子类实例化过程中是并没有被实例化,java中new子类没有实例化父类,只是调用父类的构造方法初始化了,子类从父类继承来的属性,这个调用是子类的对象调用的父类的 ...
- B/S,C/S简单介绍
B/S,C/S 架构 硬件环境不同:C/S 一般建立在专用的网络上, 小范围里的网络环境, 局域网之间再通过专门服务器提供连接和数据交换服务. B/S 建立在广域网之上的, 不必是专门的网络硬件环境, ...
- TimeSpan 结构(struct)
TimeSpan 是结构类型(struct),即值类型,可以通过两个DateTime(struct)之差来获得,如下例子: DateTime departure = new DateTime(2010 ...
- 滚动条——WPF ScrollViewer的应用
WPF ScrollViewer的应用 我们知道在一个限定高的窗体和容器中,想要把内容显示完是有些问题的,这个时候我们就要使用类似于浏览器的那个滚动条的效果了,在wpf中也同样如此,最近就碰到了这 ...
- java枚举和constant使用区别
本文结合<Effective Java>第六章前半部分关于枚举的介绍和自己的理解及实践,讲解了Java枚举的知识点.文章发布于专栏Effective Java,欢迎读者订阅. 前言 你代 ...
- 基于suse linux系统的cacti系统部署——rpm包方式
豆丁 http://www.docin.com/p-191889788.html rpm包方式:啊扬--沙迳:2010-12-1:更改:2011/5/16:一.Cacti的简介(来源:网络):Cact ...
- Openstack Mitaka 负载均衡 LoadBalancerv2
最近研究了一下Openstack负载均衡,yum源和源码级别的安装都尝试成功了.网上有很多文章都是LoadBalancerv1,这个已经被放弃了.所以写一下自己是如何使用LoadBalancerv ...