题面

这种比赛时只有11个人做出来的题一般来说都是暴难的, 我也不知道我怎么搞出来的www

看完这个题第一感觉就是要容斥,至少有一条某种边的方案已经比较难求了,而直接算三种边都至少存在一条的方案数就更难了2333

那么不妨考虑从反面容斥吧

设把三种边的存在情况表示成三进制的话,1表示至少有一条 ,0表示一条都没有,?表示这种边没有限制,那么容斥可以得到的是 : f[111] = f[???] - (f[0??]+f[?0?]+f[??0]) + (f[00?]+f[0?0]+f[?00]) - f[000]

证明可以通过二项式系数的关系导出,并且可以推广到N维形式。

显然等号右边的每个f[]都是比较好求的(但是会涉及很多算法),不过注意一些f[]是恒等的(根据图的对称性可得),所以不用每个f[]都去写一个函数算。算等号右边的f[]贡献了本题的大部分码量,这里就不一个一个说了,相信你们都能想出来的hhhhh

最后注意一下f[000],当且仅当 m==0 时 f[000]=2^n;否则 f[000]=0。

我一开始就因为这个WA了,想当然以为不可能每种边都没有(I'm reall a bro in bro),即 f[000]=0.

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1200005; int n,m,v[55],p[55],M,f[N];
bool g[55][55];
ll ans,all; inline bool Can(int S,int ad){
for(int i=0;i<M;i++)
for(int j=i+1;j<M;j++) if(g[i+ad][j+ad]&&((1<<i)&S)&&((1<<j)&S)) return 0;
return 1;
} inline void Get1(){
for(int s=0;s<(1<<M);s++) if(Can(s,0)) f[s]++;
} inline void maintain(){
for(int i=0;i<M;i++)
for(int j=0;j<(1<<M);j++) if(!((1<<i)&j)) f[j|(1<<i)]+=f[j];
} inline ll Get2(){
ll an=0;
for(int s=0,now,al=(1<<M)-1;s<(1<<(n-M));s++) if(Can(s,M)){
now=0;
for(int i=M;i<n;i++) if((1<<(i-M))&s)
for(int j=0;j<M;j++) if(g[i][j]) now|=1<<j;
an+=f[al^now];
}
return an;
} inline ll solve1(){
/* meet in the middle:
一半: 枚举合法二进制并用FMT的处理(类似高维每维值域{0,1}的前缀和)
映射到所有包含它的二进制上 另一半: 枚举合法二进制,直接找FMT数组对应的位置加就OK了
*/
Get1();
maintain();
return Get2();
} int getfa(int x){ return p[x]==x?x:(p[x]=getfa(p[x]));} inline ll solve2(){
ll an=1;
for(int i=0;i<n;i++) p[i]=i; for(int i=0,fa,fb;i<n;i++)
for(int j=i+1;j<n;j++) if(g[i][j]){
fa=getfa(i),fb=getfa(j);
if(fa!=fb) p[fa]=fb;
} for(int i=0;i<n;i++) if(v[getfa(i)]!=2) v[p[i]]=2,an<<=1; return an;
} inline ll solve3(){
ll an=1; for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++) if(g[i][j]) v[i]=v[j]=3;
for(int i=0;i<n;i++) if(v[i]!=3) an<<=1; return an;
} bool color(int x,int c){
v[x]=c;
for(int i=0;i<n;i++) if(g[x][i])
if(v[i]==v[x]) return 0;
else if(v[i]<4&&!color(i,9-c)) return 0;
return 1;
} inline ll solve4(){
ll an=1; for(int i=0;i<n;i++) if(v[i]<4)
if(!color(i,4)) return 0; else an<<=1; return an;
} int main(){
scanf("%d%d",&n,&m),all=(1ll<<n)-1,M=n+1>>1;
if(!m) ans-=all+1;//000 type
for(int U,V;m;m--)
scanf("%d%d",&U,&V),U--,V--,g[V][U]=g[U][V]=1; ans+=all+1;// ??? type
ans-=2*solve1();// 0?? and ??0 type , cause its symmetry , we can simply double the ans
ans-=solve2();// ?0? type
ans+=2*solve3();// ?00 and 00? type , similar to solve1()
ans+=solve4();//0?0 type cout<<ans<<endl;
return 0;
}

  

Codeforces 1221 G Graph And Numbers的更多相关文章

  1. [codeforces 549]G. Happy Line

    [codeforces 549]G. Happy Line 试题描述 Do you like summer? Residents of Berland do. They especially love ...

  2. Codeforces 385C Bear and Prime Numbers

    题目链接:Codeforces 385C Bear and Prime Numbers 这题告诉我仅仅有询问没有更新通常是不用线段树的.或者说还有比线段树更简单的方法. 用一个sum数组记录前n项和, ...

  3. CodeForces 794 G.Replace All

    CodeForces 794 G.Replace All 解题思路 首先如果字符串 \(A, B\) 没有匹配,那么二元组 \((S, T)\) 合法的一个必要条件是存在正整数对 \((x,y)\), ...

  4. Codeforces 1207 G. Indie Album

    Codeforces 1207 G. Indie Album 解题思路 离线下来用SAM或者AC自动机就是一个单点加子树求和,套个树状数组就好了,因为这个题广义SAM不能存在 \(len[u] = l ...

  5. Codeforces 385C Bear and Prime Numbers(素数预处理)

    Codeforces 385C Bear and Prime Numbers 其实不是多值得记录的一道题,通过快速打素数表,再做前缀和的预处理,使查询的复杂度变为O(1). 但是,我在统计数组中元素出 ...

  6. Codeforces 724 G Xor-matic Number of the Graph 线性基+DFS

    G. Xor-matic Number of the Graph http://codeforces.com/problemset/problem/724/G 题意:给你一张无向图.定义一个无序三元组 ...

  7. codeforces gym100801 Problem G. Graph

    传送门:https://codeforces.com/gym/100801 题意: 给你一个DAG图,你最多可以进行k次操作,每次操作可以连一条有向边,问你经过连边操作后最小拓扑序的最大值是多少 题解 ...

  8. Codeforces 1082 G - Petya and Graph

    G - Petya and Graph 思路: 最大权闭合子图 对于每条边,如果它选了,那么它连的的两个点也要选 边权为正,点权为负,那么就是求最大权闭合子图 代码: #pragma GCC opti ...

  9. @codeforces - 1221G@ Graph And Numbers

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 n 点 m 边的无向图. 现在要求给每个点写上 0 或 ...

随机推荐

  1. spring cloud微服务实践四

    spring cloud的hystrix还有一个配搭的库hystrix-dashboard,它是hystrix的一款监控工具,能直观的显示hystrix响应信息,请求成功率等.但是hystrix-da ...

  2. 用c++ sttring检测名字是否有空格

    name.find(' ') == std::string::npos//npos==-1,表示没找到

  3. Maven项目上总有一个小红叉问题

    一.maven project facet dynamic web module错误解决方案 在Eclipse中使用maven创建web-app的过程中总会遇到一个问题,cannot change v ...

  4. Vue.js面试题整理(转载)

    一.什么是MVVM? MVVM是Model-View-ViewModel的缩写.MVVM是一种设计思想.Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑:View 代表UI ...

  5. 分布式爬虫-bilibili评论

    实属课程需要,不然早就放弃在半路了.维持了断续半个多月的 bug 调试,突然就实现了.很是欣慰.网上关于分布式爬虫的都是一些介绍,实战的不多并且都很相似,说的云来雾去的,只是项目的流程.可能是项目一路 ...

  6. SPI学习笔记1

    SPI 简介 SPI 是英语 Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口.是 Motorola首先在其 MC68HCXX 系列处理器上定义的. SPI ...

  7. 剑指Offer编程题(python)——二叉树

    1.重建二叉树 """ 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如输入前序遍历序列{1,2,4 ...

  8. 5.Hbase API 操作开发

    Hbase API 操作开发需要连接Zookeeper进行节点的管理控制 1.配置 HBaseConfiguration: 包:org.apache.hadoop.hbase.HBaseConfigu ...

  9. Spring的使用及Spring3.2控制器增强@ControllerAdvice

    在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component. @Controller.@Service等这些注解的类,则把这 ...

  10. Python一些细节

    1.python set() dict() 有序问题,不同版本之间的差异,与Java/C++的对比 https://www.cnblogs.com/niuxichuan/p/11608386.html ...