[CEOI2019] Amusement Park
题外话。昨天学了二项式反演,感觉好玄乎的亚子。其实蒟蒻觉得二项式反演就是为了证明小学奥数的那个容斥原理的系数为什么是
说回题目。首先我们需要思考的是最后得到的有向无环图到底应该是什么样子的。正如其它题解所说,假如能用
然后考虑如何求方案数。点数很小考虑状压。用
最后来考虑重复的问题。举个栗子。假如有一张图,3 个点,连边方式是 3 和其它两个点有边。那么会发现枚举
既然有重复就想到通过容斥来解决问题。这一部分其它题解有详细阐述,不再多说。
最后提醒一句,这种题目要注意取模。
#include<bits/stdc++.h>
//#define zczc
#define int long long
const int mod=998244353;
const int N=18;
const int S=1<<N;
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
inline int qpow(int s1,int s2){
if(s2==1)return s1;
int an=qpow(s1,s2>>1);
if(s2&1)return an*an%mod*s1%mod;
else return an*an%mod;
}
int m,n,a[N*N],b[N*N],f[S],cnt[S];
bool c[S];
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
read(m);read(n);
for(int i=1;i<=n;i++){
read(a[i]);read(b[i]);
a[i]--,b[i]--;
}
for(int i=1;i<(1<<m);i++){
cnt[i]=cnt[(i>>1)]+(i&1);
for(int j=1;j<=n;j++){
if((i&(1<<a[j]))&&(i&(1<<b[j])))c[i]=true;
}
}
f[0]=1;
for(int i=1;i<(1<<m);i++){
for(int j=i;j;j=(j-1)&i){
if(c[j])continue;
f[i]=(f[i]+f[i-j]*((cnt[j]&1)?1:-1)%mod)%mod;
}
}
printf("%lld",(f[(1<<m)-1]*qpow(2,mod-2)%mod*n%mod+mod)%mod);
return 0;
}
一如既往,万事胜意
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具