至今觉得这场 edu 的 G 比 EF 都要简单……

不知道为什么出题人要把 \(m=0\) 放进去,先特判掉。

要求至少一个 \(0\),至少一个 \(1\),至少一个 \(2\),容斥一波,变成总方案数-没有 \(0\)-没有 \(1\)-没有 \(2\)+没有 \(01\)+没有 \(02\)+没有 \(12\)+没有 \(012\)。

没有 \(0\) 和没有 \(2\) 比较难搞,放到最后讨论。

没有 \(1\),考虑一个联通块,这个联通块所有数都一样,方案数是 \(2^{cnt}\),其中 \(cnt\) 是联通块个数。

没有 \(01\),也就是只有 \(2\),如果一个联通块中没有边(单独一个点),那么当然可以随便放,否则这个联通块所有数都是 \(1\)。方案数 \(2^{cnt2}\),其中 \(cnt2\) 是单独一个点的联通块个数。

没有 \(02\),也就是只有 \(1\),等价于将这个图黑白染色的方案数。如果可以黑白染色,那么方案数是 \(2^{cnt}\),否则是 \(0\)。

没有 \(12\),和没有 \(01\) 一样。方案数是 \(2^{cnt2}\)。

没有 \(012\),因为 \(m\ne 0\),显然不可能。方案数为 \(0\)。

接下来就考虑没有 \(0\) 的方案数(没有 \(2\) 是一样的)。

这个数据范围很明显是让我们折半搜索。我们不妨先搜后半部分。

对于每个合法的后半部分(即没有两个是 \(0\) 的点相邻),前半部分有哪些点不能是 \(0\) 我们是知道的。

转变一下,变成当前半部分选取的 \(0\) 点集合为 \(S\) 时,后半部分有多少种方案 \(val_S\)。(我是这么写的)

满足条件的 \(S\) 就是不能选的点的补集的子集。

实际上,在补集的 \(val\) 加个 \(1\),搜完后再做高维后缀和就能得到真的 \(val_S\)。应该不难理解。

然后再搜前半部分,对每个合法方案都加上它的 \(val\) 就行了。

时间复杂度,如果前半部分有 \(T\) 个点,复杂度是 \(O(2^TT+2^{n-T})\)。

由于我比较懒,我就取了 \(T=\frac{n}{2}\)。实际上要是 \(T\) 控制得够好,应该可以跑过 \(n=50\)。(取 \(T=23\),大概是 3e8,3.5s+CF 神机应该没问题)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=1048576;
#define MP make_pair
#define PB push_back
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline ll read(){
char ch=getchar();ll x=0,f=0;
while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return f?-x:x;
}
int n,m,cnt,cnt2,bar,lim;
ll e[40],ans,val[maxn];
bool ind[40],vis[40],col[40],flag=true;
void dfs(int u){
vis[u]=true;
FOR(v,0,n-1) if((e[u]>>v)&1){
if(!vis[v]) col[v]=col[u]^1,dfs(v);
else{
if(col[v]!=(col[u]^1)) flag=false;
}
}
}
void dfs1(int dep,ll st,ll used){
if(dep==bar) return void(val[(~st)&(lim-1)]++);
dfs1(dep-1,st,used);
if(!((st>>dep)&1)) dfs1(dep-1,st|e[dep],used|1<<dep);
}
void dfs2(int dep,ll st,ll used){
if(dep==bar+1) return void(ans-=2*val[used&(lim-1)]);
dfs2(dep+1,st,used);
if(!((st>>dep)&1)) dfs2(dep+1,st|e[dep],used|1<<dep);
}
int main(){
n=read();m=read();
if(!m) return puts("0"),0;
FOR(i,0,n-1) ind[i]=true;
FOR(i,1,m){
int u=read()-1,v=read()-1;
e[u]|=1ll<<v;e[v]|=1ll<<u;
ind[u]=ind[v]=false;
}
FOR(i,0,n-1) if(ind[i]) cnt2++;
FOR(i,0,n-1) if(!vis[i]) cnt++,dfs(i);
ans=(1ll<<n)-(1ll<<cnt)+(1ll<<cnt2)+(1ll<<cnt2)+(flag?1ll<<cnt:0);
bar=(n-1)/2;lim=1<<(bar+1);
dfs1(n-1,0,0);
for(int i=1;i<lim;i<<=1)
for(int j=0;j<lim;j+=i<<1)
FOR(k,0,i-1) val[j+k]+=val[i+j+k];
dfs2(0,0,0);
printf("%lld\n",ans);
}

CF1221G Graph And Number(容斥,搜索,FMT)的更多相关文章

  1. XTU 1242 Yada Number 容斥

    Yada Number Problem Description: Every positive integer can be expressed by multiplication of prime ...

  2. [BZOJ1853][Scoi2010]幸运数字 容斥+搜索剪枝

    1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 3202  Solved: 1198[Submit][Status ...

  3. bzoj 1853 容斥 + 搜索

    思路:先把所有幸运数字找出来, 把没有用的去掉,然后爆搜容斥,因为最多只会搜十几个就超过限制了, 所以是可行的. #include<bits/stdc++.h> #define LL lo ...

  4. 2019.01.17 bzoj1853: [Scoi2010]幸运数字(容斥+dfs)

    传送门 搜索菜题,然而第一次没有注意然后爆longlonglong longlonglong了. 题意:称所有数位由6,86,86,8组成的数为幸运数字,问一个一个区间[l,r][l,r][l,r]中 ...

  5. 【LOJ#6072】苹果树(矩阵树定理,折半搜索,容斥)

    [LOJ#6072]苹果树(矩阵树定理,折半搜索,容斥) 题面 LOJ 题解 emmmm,这题似乎猫讲过一次... 显然先\(meet-in-the-middle\)搜索一下对于每个有用的苹果数量,满 ...

  6. [HAOI2015]按位或(min-max容斥,FWT,FMT)

    题目链接:洛谷 题目大意:给定正整数 $n$.一开始有一个数字 $0$,然后每一秒,都有 $p_i$ 的概率获得 $i$ 这个数 $(0\le i< 2^n)$.一秒恰好会获得一个数.每获得一个 ...

  7. 【BZOJ1853】幸运数字(搜索,容斥)

    [BZOJ1853]幸运数字(搜索,容斥) 题面 BZOJ 洛谷 题解 成功轰下洛谷rk1,甚至超越了一个打表选手 这题思路很明显吧,先搞出来所有范围内的合法数字,然后直接容斥, 容斥的话显然没有别的 ...

  8. bzoj 4036 按位或 —— min-max容斥+FMT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4036 min-max容斥:https://blog.csdn.net/ez_2016gdgz ...

  9. HDU - 4059: The Boss on Mars (容斥 拉格朗日 小小的优化搜索)

    pro: T次询问,每次给出N(N<1e8),求所有Σi^4 (i<=N,且gcd(i,N)==1) ; sol:  因为N比较小,我们可以求出素因子,然后容斥.  主要问题就是求1到P的 ...

随机推荐

  1. HTML5新属性在Google浏览器中不能显示的问题

    这两天在学习HTML5新属性时遇到了如下问题,很是不解: 例如在学习使用canvas时,需要绘制一个红色的原点,代码如下: <!DOCTYPE HTML> <html> < ...

  2. tushare+pandas实现财经数据分析

    写在前面的话: 这是一个优秀的财经接口包,博主平时工作中也有使用,觉得很好,现在分享一些使用心得给需要的人,tushare并不是一个炒股软件,只是一个提供pandas数据的工具,具体如何使用,因人而异 ...

  3. js的事件循环(Event Loop)

    (本文从掘金小册整理) 首先介绍一下几个概念 进程与线程 相信大家经常会听到 JS 是单线程执行的,但是你是否疑惑过什么是线程? 讲到线程,那么肯定也得说一下进程.本质上来说,两个名词都是 CPU 工 ...

  4. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 4

    18.4  创建PDO对象 使用PDO在与不同数据库管理系统之间交互时,PDO对象中的成员的方法是统一各种数据库的访问接口,所以在使用PDO与数据库交互之前,首先要创建一个PDO对象.在通过构造方法创 ...

  5. 鸟哥的Linux私房菜笔记第五章,文件权限与目录配置(二)

    Linux目录配置的依据--FHS 因为利用Linux来开发产品的公司太多,例如,CentOS.Ubuntu.ReHat...,导致了配置文件存放的目录没有统一的标准.后来就有了FHS(Filesys ...

  6. VMWare 虚拟机启动报“内部错误”的解决办法

    情况 启动虚拟机的时候,启动不起来,弹出对话框,内部错误. 原因 Vmware 的 server 服务未开启. 解决办法 将以上服务都启动起来

  7. Unity API学习笔记(1)

    首先创建测试项目: 这里我选择了2D,其实都可以,之后可以在项目中修改. 修改方法: 进入正题. 首先看一下官方提供的>手册和>脚本API文档. 创建C#脚本文件并打开: 默认的脚本文件为 ...

  8. 2019年上半年收集到的人工智能LSTM干货文章

    2019年上半年收集到的人工智能LSTM干货文章 门控神经网络:LSTM 和 GRU 简要说明 LSTM-CNN-Attention算法系列之一:LSTM提取时间特征 对时间序列分类的LSTM全卷积网 ...

  9. Android 布局测试

    wrap_content <Button android:id="@+id/button1" android:layout_width="wrap_content& ...

  10. 开关VoLTE流程分析(一)

    开关按钮位置: 设置--> 更多--> 移动网络--> 增强型4G LTE模式 控件初始化addEnhanced4GLteSwitchPreference,该设置开关使用了Switc ...