CF1221G Graph And Number(容斥,搜索,FMT)
至今觉得这场 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);
}
原文地址:https://www.cnblogs.com/1000Suns/p/11566940.html
- 一个特殊场景的 LR 预测优化 Trick
- 你知道Unity IoC Container是如何创建对象的吗?
- 发布一个锁定行列的一种方法。(实现Excel里的冻结窗格的功能)
- IoC+AOP的简单实现
- 使用了继承、多态还有工厂模式和反射,但是还是没有OO的感觉。[已经增加了实现的代码]
- OO——从不知到知道一点,从迷茫到豁然开朗 (迟来的我的2002到2007)
- 只在UnitTest和WebHost中的出现的关于LogicalCallContext的严重问题
- TEST LAB V8在线渗透实验室教程(三)
- CMQ请求域名
- 在Entity Framework中使用存储过程(一):实现存储过程的自动映射
- 在Entity Framework中使用存储过程(二):具有继承关系实体的存储过程如何定义?
- 表单控件的副产品——查询控件
- 表单控件续(1)——应用接口来简化和分散代码
- 通过自定义配置实现插件式设计
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 数据处理|数据查重怎么办?去重,就这么办!
- FFmpeg合并MP4文件
- Broom |tidy up a bit,模型,检验结果一键输出!
- 今日算法题-动态规划法
- 3分钟短文 | PHP获取函数的代码片段,唯有反射最高效!
- ggforce|绘制区域轮廓-区域放大-寻找你的“onepiece”
- 基因矩阵转置文件格式(* .gmt)
- gganimate|创建可视化动图,让你的表会说话
- ggplot2|玩转Manhattan图-你有被要求这么画吗?
- deconstructSigs|探寻cosmic的独特“气质”-mutation signature !
- barplot3d|圣诞节送你一个mutation signature搭建的“乐高”
- R读取gmt文件
- 一个画双层pie图的函数
- DEapp(差异表达分析)本地版——自由飞翔
- 盘一盘Tidyverse| 筛行选列之select,玩转列操作