[CF1221G] Graph And Numbers
传送门:https://codeforces.com/contest/1221/problem/G
sol:
感觉这个G题还挺好搞的……
首先同时有,,正面统计好像不大好统计
那就反过来
总方案数
然后要减去没有的方案,没有的方案,没有的方案,加上没有的方案,没有的方案,没有的方案,减去没有的方案
我们分开讨论
显然 没有的方案数和没有的方案数是等价的
没有的方案:考虑把填设为,其他设为,好像有点大 拆半找 然后对于一个确定的前半部分 后半部分不能选的方案就确定了,然后枚举后半部分取法 然后加上合法的前半边的计数就行了
没有的方案:即一个联通块内同时填或,设联通块数为,答案为
没有的方案:即只有的方案,这个时候可以发现,除了孤点,其他的点都填入,只需要统计孤点的数量,设为,答案为
没有的方案:即只有的方案,也就是说这时候是……这样交替填入。如果有奇环则不合法,如果没有奇环,答案为,否则是
没有的方案:只有的方案,这时候和只有的方案等价
没有的方案 如果 答案为,否则为
思路大概就这样233
代码可能有点麻烦
Code:
#include <bits/stdc++.h> using namespace std; int N,M; int vis[55]; vector <int> qwq[40]; long long Right[45],cntRight[1<<20]; long long Onl(){ long long ans=0; for (int i=0;i<N;i++) if (qwq[i].size()==0) ans++; return ans; } void dfs(int Now,int x){ if (vis[Now]) return; vis[Now]=x; for (int i=0;i<qwq[Now].size();i++) dfs(qwq[Now][i],3-x); } long long GetComponents(){ memset(vis,0,sizeof(vis)); long long ans=0; for (int i=0;i<N;i++) if (!vis[i]){ ans++; dfs(i,1); } return ans; } long long Get02(){ long long m1=min(N,20); long long m2=N-m1; memset(cntRight,0,sizeof (cntRight)); for (long long i=0;i<(1ll<<m1);i++){ long long Nowmas=0; bool flag=true; for (int j=0;j<m1;j++){ if ((i&(1ll<<j))==0) continue; if (Nowmas&(1ll<<j)) flag=false; Nowmas|=((1ll<<j)|Right[j]); } if (flag) cntRight[Nowmas>>m1]++; } for (int i=0;i<m2;i++) for (int j=0;j<(1<<m2);j++) if (j&(1ll<<i)) cntRight[j]+=cntRight[j^(1ll<<i)]; long long ans=0; for (long long i=0;i<(1<<m2);i++){ long long Nowmas=0; bool flag=true; for (int j=m1;j<N;j++){ if ((i&(1<<(j-m1)))==0) continue; if (Nowmas&(1ll<<j)) flag=false; Nowmas|=(1ll<<j)|Right[j]; } if (flag) ans += cntRight[i^((1ll<<m2)-1)]; } return ans; } bool Non_Odd(){ memset(vis,0,sizeof(vis)); for (int i=0;i<N;i++) if (!vis[i]) dfs(i,1); for (int i=0;i<N;i++){ for (int j=0;j<qwq[i].size();j++) if (vis[i]==vis[qwq[i][j]]) return false; } return true; } long long Pow(long long x,long long y){ long long ans=1; for (;y;y>>=1){ if (y&1) ans=ans*x; x=x*x; } return ans; } long long Calc(int Mask){ if (Mask==0) return Pow(2,N); if (Mask==1||Mask==4) {return Get02();} if (Mask==2){return Pow(2,GetComponents());} if (Mask==3||Mask==6){return Pow(2,Onl());} if (Mask==5){if (Non_Odd()) return Pow(2,GetComponents());else return 0;} if (Mask==7) {if (M==0) return Pow(2,N);else return 0;} } int main(){ scanf("%d%d",&N,&M); for (int i=0;i<M;i++){ int x,y; scanf("%d%d",&x,&y); --x;--y; qwq[x].push_back(y); qwq[y].push_back(x); Right[x]^=(1ll<<y); Right[y]^=(1ll<<x); } long long ans=0; for (int i=0;i<8;i++){ if (__builtin_popcount(i)%2==0) ans+=Calc(i); else ans-=Calc(i); } cout<<ans; return 0; }
干啥啥不行
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?