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 ...
随机推荐
- Ctrl+Z 暂停程序及重启程序【转】
本文转自:https://blog.csdn.net/duyiwuer2009/article/details/43191799 Ctrl+Z - 暂停进程并放入后台 jobs - 显示当前暂停的进程 ...
- uitableview 侧滑删除
https://github.com/MortimerGoro/MGSwipeTableCell
- orecle触发器
一.触发器简介 触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行.因此触发器不需要人为的去调用,也不能调用.然后,触发器的触发条件其实在你定义的时候就已经设定好了.这里面需 ...
- BI项目中的ETL设计详解(数据抽取、清洗与转换 )(转载)
原文:http://www.cnblogs.com/reportmis/p/5939732.html ETL是BI项目最重要的一个环节,通常情况下ETL会花掉整个项目的1/3的时间,ETL设计的好坏直 ...
- Mac Item2 SSH免密登录Linux 服务器的两种方式
转自http://blog.csdn.net/jobschen/article/details/52823980 mac ssh登录linux服务器 的两种方式: 个人推荐第二种,zsh方式,只需要把 ...
- android studio 慢的问题
转自:http://www.jianshu.com/p/e1c0b46e317c 在使用Android studio的时候常常遇到这样的问题,从github或是其他地方导入项目,Android stu ...
- echarts3结合openlayers2实现Map类型图表
网上查阅了部分资料,有些是用echarts2实现的,因echarts2无法满足项目中其他部分的要求,故只能采用echarts3(2017/9/18,echarts3官网突然把基于geo的demo下架了 ...
- Java条件语句之 if...else
if...else 语句的操作比 if 语句多了一步: 当条件成立时,则执行 if 部分的代码块: 条件不成立时,则进入 else 部分.例如,如果考试成绩大于 90 分,则奖励一个 IPHONE ...
- shell 数组操作
1. 定义数组: var_array=(one two three four five) 2.常用操作 获取数组长度: ${#var_array[@]} 获取所有数组元素: ${var_array[ ...
- 【sparkSQL】创建DataFrame及保存
首先我们要创建SparkSession val spark = SparkSession.builder() .appName("test") .master("loca ...