题面

这种比赛时只有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. Django中的Object Relational Mapping(ORM)

    ORM 介绍 ORM 概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用 ...

  2. s5p6818裸机程序的设计:以GPIO为例

    为了调试方便,首先确保对于硬件的控制没有问题. Makefile # Makefile edited by Schips # 2019-06-21 schips@dingtalk.com # 文件类型 ...

  3. canvas绘制文本自动换行

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  4. Nginx安装配置|Nginx反向代理|Nginx支持HTTPS|Nginx重定向

    Nginx安装配置 可以直接看到最下面的HTTPS. Nginx安装 我的系统如下: No LSB modules are available. Distributor ID: Ubuntu Desc ...

  5. (二)Redis之Jedis概念和HelloWorld实现以及JedisPool的使用

    一.Jedis概念 实际开发中,我们需要用Redis的连接工具连接Redis然后操作Redis, 对于主流语言,Redis都提供了对应的客户端: 官网:https://redis.io/clients ...

  6. (四)springmvc之获取servlet原生对象

    一.使用DI注入的方式 <a href="<%=request.getContextPath()%>/servletObj_1">DI注入的方式</a ...

  7. java 框架-分布式服务框架1ZooKeeper

    https://www.cnblogs.com/felixzh/p/5869212.html Zookeeper的功能以及工作原理   1.ZooKeeper是什么?ZooKeeper是一个分布式的, ...

  8. ajax:用于创建快速动态网页的技术

    ajax是一种用于创建快速动态网页的技术. 异步的javascript和XML(JSON),主要是完成一个局部刷新. 异步:你传输吧,我先干我自个儿的事,你传好了告诉我一声 同步:你传输,我停下活儿看 ...

  9. SpringCloud之RabbitMQ消息队列原理及配置

    本篇章讲解RabbitMQ的用途.原理以及配置,RabbitMQ的安装请查看SpringCloud之RabbitMQ安装 一.MQ用途 1.同步变异步消息 场景:用户下单完成后,发送邮件和短信通知. ...

  10. Java基础加强-类加载器

    /*类加载器*/ 把.class文件从硬盘上加载出来,将类的字节码(二进制)加载到内存中 /*类加载器及其委托机制*/ Java虚拟机中可以安装多个类加载器(可以自己编写),系统默认三个主要类加载器, ...