当前位置: 首页 > news >正文

[GDKOI2023 提高组] 异或图 题解

[GDKOI2023 提高组] 异或图

先考虑 \(m=0\) 怎么做,发现问题很像数位 DP,但是由于有 \(n\) 个数,直接 \(O(2^n)\) 记录每个数是否顶到上界非常劣。不过可以借鉴数位 DP 的思想,如果在第 \(w\) 位出现了自由元(第一次脱离上界),不妨设这个数是 \(a_1\),那么 \(b_1\)\([0,w-1]\) 位可以乱填,此时 \(b[2,n]\)\([0,w-1]\) 位随便填都可以通过 \(b_1\) 来调整使得它合法。
于是从大往小枚举 \(w\),钦定 \(\forall b_i\)\(a_i\)\([w+1,\log V]\) 位都相同,第 \(w\) 位出现了一个自由元,计算此时的方案数(如果此时 \(w+1\) 位及以上和 \(C\) 不相同就结束)。可以设计 DP,设 \(dp_{i,0/1,0/1}\) 表示考虑了前 \(i\) 个数,当前第 \(w\) 位的异或和,是否出现过自由元。转移枚举 \(b_i\) 的第 \(w\) 位填什么,如果 \(b_i\) 是第一个自由元那么系数为 \(1\),否则系数为 \(b_i\text{ 在 [0,w-1] 位填数的方案数}\)
这个子问题复杂度 \(O(n\log V)\)


原问题很容易想到 \(O(2^m)\) 进行容斥,对于一个边集 \(E\) 的容斥系数为 \((-1)^{|E|}\),计算答案时考虑每一个连通块,显然一个连通块的限制只跟其中 \(a_i\) 的最小值有关,设为 \(mn\),对于偶数大小连通块直接令答案乘上 \(mn+1\),对于奇数大小连通块把他们的 \(mn\) 全部拿出来跑一开始的子问题。

发现计算答案时我们只关心连通块的情况,并不关心连通块里的边是怎么连的,所以不妨直接枚举连通块是怎么划分的,考虑怎么计算此时的容斥系数:首先不同连通块的容斥系数直接乘起来即可,对于一个连通块 \(S\),设 \(S\) 内的点之间的边的集合为 \(U\),他的容斥系数 \(g_S=\sum_{E\subseteq U,\text{边集 E 能让 S 连通}} (-1)^{|E|}\)。计算 \(g_S\) 可以容斥 \(O(3^n)\) 计算,设 \(h_S=\sum_{E\subseteq U} (-1)^{|E|}=[|U|=0]\),则 \(g_S=h_S-\sum_{T\subsetneqq S,lowbit(T)=lowbit(S)} g_Th_{S/T}\)
直接枚举连通块划分是 \(O(Bell(n)n\log V)\) 的,还是过不去。

沿用之前 \(O(2^m) \to O(Bell(n))\) 的优化思路,计算答案的时候我们需要的只是每个连通块大小的奇偶性以及这个连通块的 \(mn\),至于这个连通块具体是咋样的只会影响容斥系数。为了简便,我们可以把偶数连通块的 \((mn+1)\) 也看成容斥系数的一部分,这样我们就只需要考虑奇数连通块的 \(mn\) 了。
为了更方便的处理 \(mn\) 我们可以把所有点按照 \(a_i\) 升序排序并重标号,如果一个点是奇数连通块的最小值(\(a_i\) 相同比较编号),则称他为关键点,我们可以直接 \(O(2^n)\) 枚举关键点集合 \(S\) 并跑一开始的子问题,现在要解决的仅仅只是 \(S\) 的容斥系数的问题。
划分连通块的过程可以看成是每次选出最小的没有被选择过的点 \(i\) 作为一个新的连通块的 \(mn\),然后从 \([i+1,n]\) 中选择一些没被选过的点和他组成连通块。于是发现对于 \(\le i\) 的点,他们一定已经被划分好了,只需要记录 \(0/1\) 表示他们是否是关键点;对于 \(>i\) 的点,也只需要记录 \(0/1\) 表示他们是否已经被划分到某个连通块中。所以可以直接设状态 \(f_{i,S}\) 表示分界点是 \(i\),每个点的 \(0/1\) 状态为 \(S\) 的容斥系数,我们要的就是 \(f_{n,S}\)。这个 DP 的状态数 \(O(n2^n)\),复杂度 \(O(n3^n)\)

总复杂度 \(O(n3^n+2^nn\log V)\)

code

#include<bits/stdc++.h>
#define Debug puts("-------------------------")
#define LL long long 
using namespace std;
const int N=15+5,mod=998244353;
int lowbit(int x){ return x&(-x); }
void Add(int &x,int y){ x=(x+y>=mod)?(x+y-mod):(x+y); } 
int n,m,siz[(1<<15)+5],dp[N][2][2],f[N][(1<<15)+5],g[(1<<15)+5],h[(1<<15)+5],id[N];
pair<LL,int> a[N];
LL C; 
bool E[N][N];
int DP(vector<LL> &p){LL sum=0; for(LL x:p) sum^=x;int res=(sum==C),len=p.size();for(int w=59;w>=0;w--){ for(int i=1;i<=len;i++) dp[i][0][0]=dp[i][0][1]=dp[i][1][0]=dp[i][1][1]=0;LL lst_all=(1ll<<w)-1;dp[0][0][0]=1;for(int i=0;i<len;i++){for(int o1:{0,1}){  for(int o2:{0,1}){ int val=dp[i][o1][o2];if(!val) continue;if(p[i]>>w&1){Add(dp[i+1][o1^1][o2],((p[i]&lst_all)+1)%mod*val%mod);if(o2) Add(dp[i+1][o1][1],(lst_all+1)%mod*val%mod);else Add(dp[i+1][o1][1],val); }	else Add(dp[i+1][o1][o2],((p[i]&lst_all)+1)%mod*val%mod);}}}Add(res,dp[len][C>>w&1][1]);if((sum>>w&1)!=(C>>w&1)) break;}return res;
}
signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);double beg=clock();scanf("%d%d%lld",&n,&m,&C);for(int i=1;i<=n;i++) scanf("%lld",&a[i].first),a[i].second=i;sort(a+1,a+n+1);  for(int i=1;i<=n;i++) id[a[i].second]=i;for(int i=1;i<=m;i++){int u,v; scanf("%d%d",&u,&v); u=id[u],v=id[v];E[u][v]=E[v][u]=true;}for(int S=1;S<(1<<n);S++){h[S]=1,siz[S]=__builtin_popcount(S);for(int i=0;i<n;i++) if(S>>i&1) for(int j=i+1;j<n;j++) if((S>>j&1)&&E[i+1][j+1]) h[S]=0;g[S]=h[S];for(int T=(S-1)&S;T;T=(T-1)&S) if(lowbit(S)==lowbit(T)) Add(g[S],mod-g[T]*h[S^T]);}f[0][0]=1;for(int i=0,all=(1<<n)-1;i<n;i++){  for(int S=0;S<(1<<n);S++){if(!f[i][S]) continue;if(S>>i&1){  //注意点 i+1 对应第 i 位 Add(f[i+1][S^(1<<i)],f[i][S]);continue;} int S1=S&((1<<i)-1),S2=S^S1,T=(S^all)>>(i+1)<<(i+1);for(int S3=T;;S3=(S3-1)&T){int val=1ll*f[i][S]*g[(1<<i)^S3]%mod;if((siz[S3]+1)&1) Add(f[i+1][S1^(1<<i)^(S2^S3)],val);else Add(f[i+1][S1^(S2^S3)],(a[i+1].first+1)%mod*val%mod);if(!S3) break;}}}int ans=0;for(int S=0;S<(1<<n);S++){vector<LL> p;for(int i=0;i<n;i++) if(S>>i&1) p.emplace_back(a[i+1].first);Add(ans,1ll*DP(p)*f[n][S]%mod); } printf("%d\n",ans); cerr << "Time: " << (clock()-beg) << endl;return 0;
}
http://www.jsqmd.com/news/274079/

相关文章:

  • 2026ktv音响设备厂家权威推荐榜单:音响设备专卖/会议室音响设备/灯光音响设备/专业音响设备源头厂家精选。
  • 四个关键性能指标分析表
  • 2026口碑优选:副主任医师备考题库Top10排名,综合评分与实测反馈 - 医考机构品牌测评专家
  • 智能工厂发展报告(2025 年):3.5万+崛起!趋势、行业、区域、技术全解析
  • 成都设计工作室排名:5家专业机构对比与权威推荐 - 真知灼见33
  • 横向对比!2026副主任医师十大优质题库排名,闭眼入推荐 - 医考机构品牌测评专家
  • 2026副主任医师题库哪家强?从权威性到覆盖性的十大题库排名解析 - 医考机构品牌测评专家
  • React轻量级状态管理实用的方案(useReducer + Context API)
  • 采购决策参考:2026进口滚丝机品牌服务网络、备件供应与响应时效分析 - 品牌推荐大师
  • 【图像隐写】DCT彩色图像数字水印嵌入+攻击+提取(含PSNR、NCC、MSSIM)【含GUI Matlab源码 15005期】
  • Flutter 权限管理实战手册:permission_handler 全平台适配与最佳实践 - 教程
  • UE5 C++(39):创建 TimeHandle 定时器
  • 【图像隐写】DWT数字水印嵌入+提取+攻击【含Matlab源码 15004期】
  • 哈尔滨出国英语雅思培训选课指南推荐:口碑排名前十机构全面测评 - 老周说教育
  • 2026 北京托福雅思英语培训班课程权威测评:靠谱机构口碑排名 TOP5​ - 老周说教育
  • 【计算机毕设】基于Django框架的多媒体资料管理系统的设计与实现
  • 2026Q1南京江宁区装修公司排行榜:二手房翻新,老房装修精选top5 - 品牌智鉴榜
  • 2026年1月反渗透杀菌剂厂家TOP5实力榜:这些企业值得信赖 - 深度智识库
  • 用这 9 个 API,我把页面性能干到了 90+
  • 【计算机毕设】Python房屋信息可视化及价格预测系统
  • 强烈安利10个AI论文平台,本科生搞定毕业论文!
  • 2026超级学长国际课程:多维度提升国际升学竞争力 - 品牌排行榜
  • 主流金属键盘厂家有哪些?最新口碑与实力分析报告,附5家主流企业服务模式与适配场景详解 - 速递信息
  • 2026 年靠谱地坪漆厂家全解析细分需求与真实案例 筛选避坑指南 - 深度智识库
  • 2026年辣味零食推荐,辣味零食挑选指南及选购建议 - Top品牌推荐
  • map和set
  • 导师严选2026最新!9款一键生成论文工具测评:本科生毕业论文全攻略
  • 终究还是学了SpringBoot ,Java我又双敪来了
  • Spring全家桶面试工作重点精简汇总!
  • 天津超级学长怎么样?2026天津语言培训口碑与课程解析 - 品牌排行榜