线性基笔记
本人蒟蒻如有错误还请指出打牛客时盯了一题两个小时毫无头绪一头雾水一看题解线性基人麻了于是就有了这篇文章...线性基的概念首先线性基是什么有什么用线性基是一个数的集合取线性基中若干个数异或起来可以得到原序列中的任意一个数。线性基的构造其构造方法为从最高位往低位枚举用表示为线性基中最高位为的数当一个数二进制下第位为1时如果不存在就对赋值否则将这个数异或上。如果这个数中途被异或成0了那么说明这个数可以被线性基中的一些数异或得到则不需要将这个数插到线性基中。具体则表示为这样代码则表示为void insert(int x) { for (int i 60; i 0; i--) if ((x i) 1) { if (!d[i]) { d[i] x; return; } x ^ d[i]; } zero 1; }注此处zero用于记录是否有元素无法插入到线性基中在下文求异或最小值处提到。线性基的性质性质一原序列中的任意一个数都可以通过线性基中的若干个数异或表示。因为如果无法表示那么他必然可以加到线性基中。性质二线性基中任意数异或起来不可能为0。假设^^0则^可以由^表示由性质一可知无法被插到线性基中。性质三在满足性质一条件下线性基中的数的个数最少。如果我们多插入了一个数x而x又可以由原线性基中的一些数异或得到那么这个数显然是多余的。线性基的作用求异或最大值求异或最大值本质上是一个贪心的过程。从最高位往低位枚举如果该位线性基存在并且异或后结果变大则异或上该位的线性基。int qmax() { int res 0; for (int i 60; i 0; i--) if ((res ^ d[i]) res) res ^ d[i]; return res; }求异或最小值由性质二可知线性基无法表示0因此我们要分类讨论。如果一个数无法被插入到线性基中则说明他可以被线性基中的元素表示即存在一些数的异或值为0这一点只需要用一个变量zero在插入的时候记录一下是否变成0即无法插入到线性基中即可。如果不存在0异或的异或值那么最小的线性基就是答案因为最小的线性基最高位最小值最小。int qmin() { if (zero) return 0; for (int i 0; i 60; i) if (d[i]) return d[i]; return 0; }求第k小的异或值由于线性基无法存0因此当存在0时k要先减1。我们要先对线性基做一个处理对于每一位从到枚举每一位如果存在并且的第位为1那么让的异或上。处理完后线性基中的数应该长这样最后再把新的线性基的数加到新数组p中接下来找第k小的值时只需要将k二进制拆分如果k的第位为1就异或上。注意不是异或上原线性基中元素。int query(int k) { k - zero; if (!k) return 0; for (int i 60; i 0; i--) for (int j i - 1; j 0; j--) if (d[i] (1LL j)) d[i] ^ d[j]; for (int i 0; i 60; i) if (d[i]) p[cnt] d[i]; if (k (1LL cnt)) return -1; int res 0; for (int i 0; i cnt; i) if ((k i) 1) res ^ p[i]; return res; }判断一个数是否能被线性基中的一些数异或得到只需要尝试将这个数插入到线性基中如果这个数最后变成0了即这个数不能插入到线性基中说明这个数可以被线性基中的一些数异或得到否则不能。int check(int x) { for (int i 60; i 0; i--) { if ((x i) 1) x ^ d[i]; if (x 0) return 1; } return 0; }查询一个数可以由原序列中的哪些数异或得到线性基一个非常强大的作用是可以直接找出一个数由原序列中的哪些数异或得到。这一步查询本质上是一个哈希的过程。在线性基中插入元素时我们可以同时存储这一位的哈希值当一个数由这一位异或而来时我们只需要异或上这一位的哈希值。最后再对这个哈希值做一个解码。这样我们就可以找到由哪些数异或而来了。bool insert(int val, int idx) { ull cul 0; for (int i 30; i 0; i--) if ((val i) 1) { if (!d[i]) { d[i] val; mask[i] cul | (1ull rep.size()); rep.push_back(idx); return true; } val ^ d[i]; cul ^ mask[i]; } zero 1; return false; } pairbool, ull check(int val) { ull res 0; for (int i 30; i 0; i--) { if ((val i) 1) { if (!d[i]) return {false, 0}; val ^ d[i]; res ^ mask[i]; } } return {true, res}; } vectorint choose(ull msk) { vectorint res; for (int i 0; i rep.size(); i) if ((msk i) 1) res.push_back(rep[i]); return res; }模板int zero 0, cnt 0; int d[61], p[61]; ull mask[61]; vectorint rep; bool insert(int val, int idx) { ull cul 0; for (int i 30; i 0; i--) if ((val i) 1) { if (!d[i]) { d[i] val; mask[i] cul | (1ull rep.size()); rep.push_back(idx); return true; } val ^ d[i]; cul ^ mask[i]; } zero 1; return false; } int qmax() { int res 0; for (int i 30; i 0; i--) if ((res ^ d[i]) res) res ^ d[i]; return res; } int qmin() { if (zero) return 0; for (int i 0; i 30; i) if (d[i]) return d[i]; return 0; } void rebuild() { for (int i 30; i 0; i--) for (int j i - 1; j 0; j--) if (d[i] (1LL j)) d[i] ^ d[j]; for (int i 0; i 30; i) if (d[i]) p[cnt] d[i]; } int query(int k) { k - zero; if (!k) return 0; rebuild(); if (k (1LL cnt)) return -1; int res 0; for (int i 0; i cnt; i) if ((k i) 1) res ^ p[i]; return res; } pairbool, ull check(int val) { ull res 0; for (int i 30; i 0; i--) { if ((val i) 1) { if (!d[i]) return {false, 0}; val ^ d[i]; res ^ mask[i]; } } return {true, res}; } vectorint choose(ull msk) { vectorint res; for (int i 0; i rep.size(); i) if ((msk i) 1) res.push_back(rep[i]); return res; } void clear() { for (int i 0; i 30; i) d[i] p[i] mask[i] 0; cnt 0; zero 0; rep.clear(); }题目原题链接回到这道我两个小时没有任何头绪的题我去这不一眼秒题目大意有两个长度为n的数组和构造一个数组等于或者使得^^...^等于0思路先让等于如果异或结果已经为0那么答案就为数组如果要让替换成那就异或上^。也就是说令原先数组的异或结果为如果为0答案就为数组否则就要异或上若干个^使得最后的结果为0。那么只需要找出一些^的位置使得异或结果为即可。代码void solve() { clear(); cin n; int t 0; for (int i 1; i n; i) { cin a[i]; t ^ a[i]; st[i] 0; } for (int i 1; i n; i) { cin b[i]; if ((a[i] ^ b[i]) 0) continue; insert(a[i] ^ b[i], i); } if (t 0) { for (int i 1; i n; i) cout a[i] ; cout endl; return; } auto [flag, msk] check(t); if (!flag) { cout -1 endl; return; } vectorint ans choose(msk); for (int x : ans) st[x] 1; for (int i 1; i n; i) if (st[i]) cout b[i] ; else cout a[i] ; cout endl; }参考文献线性基详解题解

相关新闻

【开题答辩全过程】以 基于Java的网上书店系统为例,包含答辩的问题和答案

【开题答辩全过程】以 基于Java的网上书店系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人,语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

2026/7/6 16:39:01 阅读更多 →
实时监控集成:Prometheus在混沌测试中的应用

实时监控集成:Prometheus在混沌测试中的应用

在分布式系统复杂度激增的当下,混沌测试已成为验证系统弹性的核心手段,而Prometheus作为云原生监控标准,其实时数据采集能力为故障注入实验提供了可观测性基石。 一、混沌测试与Prometheus监控的协同价值 混沌测试通过主动注入故障&#xf…

2026/7/5 17:24:11 阅读更多 →
【开题答辩全过程】以 基于Java的网上图书商城系统为例,包含答辩的问题和答案

【开题答辩全过程】以 基于Java的网上图书商城系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人,语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

2026/7/5 11:40:32 阅读更多 →

最新新闻

Balena Etcher终极指南:三步搞定系统启动盘的免费神器

Balena Etcher终极指南:三步搞定系统启动盘的免费神器

Balena Etcher终极指南:三步搞定系统启动盘的免费神器 【免费下载链接】etcher Flash OS images to SD cards & USB drives, safely and easily. 项目地址: https://gitcode.com/GitHub_Trending/et/etcher 还在为制作系统启动盘而烦恼吗?命令…

2026/7/6 22:59:58 阅读更多 →
5分钟高效找回QQ空间青春记忆:GetQzonehistory智能数据恢复指南

5分钟高效找回QQ空间青春记忆:GetQzonehistory智能数据恢复指南

5分钟高效找回QQ空间青春记忆:GetQzonehistory智能数据恢复指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 还在为QQ空间里那些消失的青春记忆而烦恼吗?那些…

2026/7/6 22:57:55 阅读更多 →
终极指南:如何在Switch和WiiU之间自由转换塞尔达传说旷野之息存档

终极指南:如何在Switch和WiiU之间自由转换塞尔达传说旷野之息存档

终极指南:如何在Switch和WiiU之间自由转换塞尔达传说旷野之息存档 【免费下载链接】BotW-Save-Manager BOTW Save Manager for Switch and Wii U 项目地址: https://gitcode.com/gh_mirrors/bo/BotW-Save-Manager 你是否曾经为《塞尔达传说:旷野之…

2026/7/6 22:55:53 阅读更多 →
OpenCV 4.9 与 MediaPipe 手势识别:3 种方案在树莓派 5 上的实时性能实测

OpenCV 4.9 与 MediaPipe 手势识别:3 种方案在树莓派 5 上的实时性能实测

OpenCV 4.9 与 MediaPipe 手势识别:树莓派 5 上的三种实时方案性能对比当一块信用卡大小的开发板遇上计算机视觉,会碰撞出怎样的火花?树莓派 5 凭借其升级的四核 Cortex-A76 处理器和 VideoCore VII GPU,正在边缘计算领域掀起新的…

2026/7/6 22:55:53 阅读更多 →
ICM-42688-P与PIC32MX675F512L在工业自动化中的高性能应用

ICM-42688-P与PIC32MX675F512L在工业自动化中的高性能应用

1. ICM-42688-P与PIC32MX675F512L的黄金组合解析在工业自动化和机器人控制领域,传感器与处理器的协同工作能力直接决定了系统性能上限。ICM-42688-P作为TDK InvenSense推出的6轴MEMS运动传感器,与Microchip的PIC32MX675F512L微控制器形成的解决方案&…

2026/7/6 22:55:53 阅读更多 →
openGauss 5.0 在鲲鹏920平台 NUMA 优化实战:事务吞吐提升 30% 的 3 个关键配置

openGauss 5.0 在鲲鹏920平台 NUMA 优化实战:事务吞吐提升 30% 的 3 个关键配置

openGauss 5.0在鲲鹏920平台的NUMA优化实战:3个关键配置实现30%事务吞吐提升在当今数据密集型应用爆发的时代,数据库性能优化已成为企业数字化转型的核心课题。作为国产数据库的领军者,openGauss 5.0与华为鲲鹏920处理器的深度结合&#xff0…

2026/7/6 22:53:52 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻