[ARC145E] Adjacent XOR 题解

推荐在 cnblogs 上阅读。

[ARC145E] Adjacent XOR 题解

这道题真的是道神仙题,是那种考场想不出来、补题也补得十分艰难的题。可能我还是太菜了。

看了 APJ 大神的题解,琢磨很久才懂。为了帮助像我一样的同学,特地写一篇题解。

这是 2 月的第一篇题解、更是我的第一道黑题题解,谨纪念。

参考文献

  • [1] APJifengc,「解题报告」[ARC145E] Adjacent XOR

题意

给你 n n n 个整数 a 1 , a 2 , … , a n a_1,a_2,\dots,a_n a1,a2,,an,再给你 n n n 个整数 b 1 , b 2 , … , b n b_1,b_2,\dots,b_n b1,b2,,bn。通过执行以下操作,问你能不能操作 70000 70000 70000 次以内使得 a a a b b b 相同。

  • 操作:选择整数 k ∈ [ 1 , n ] k\in[1,n] k[1,n],进行 a i ← a i − 1 ⊕ a i a_i\leftarrow a_{i-1}\oplus a_i aiai1ai i ∈ [ 2 , k ] i\in[2,k] i[2,k] 的赋值操作。

数据范围: 2 ≤ n ≤ 1000 2\le n\le 1000 2n1000 0 ≤ a i , b i < 2 60 0\le a_i,b_i \lt 2^{60} 0ai,bi<260

Solution

转化目标

题意清晰,就是告诉你要构造方案。

由于每一次操作都是 a i ← a i − 1 ⊕ a i a_i\leftarrow a_{i-1}\oplus a_i aiai1ai,这个及其难下手。不妨反过来,从 b b b 入手。

在此之前,先琢磨透这个在 a a a 上做手脚的操作,到底是个啥?

其实一次操作,钦定 k k k 以后,就是去把每一个在 [ 2 , k ] [2,k] [2,k] a i a_i ai 都赋值为原 a a a 数组下标从 1 ∼ i − 1 1\sim i-1 1i1 的异或和。

而我们对 a i a_i ai 做手脚,是因为我们期望得到 b i b_i bi。这个对 a a a 数组的操作,每次都依靠前缀。

形式化地,这样:

b 1 = a 1 ′ = a 1 b 2 = a 2 ′ = a 1 ⊕ a 2 b 3 = a 3 ′ = a 1 ⊕ a 2 ⊕ a 3 … b i = a i ′ = ⊕ j = 1 i a j b_1=a'_1=a_1\\b_2=a'_2=a_1\oplus a_2\\b_3=a'_3=a_1\oplus a_2\oplus a_3\\\dots\\b_i=a'_i=\oplus_{j=1}^i a_j b1=a1=a1b2=a2=a1a2b3=a3=a1a2a3bi=ai=j=1iaj

现在考虑从 b b b 入手,从而推出 a a a。那么题意变为:

选择 k ∈ [ 1 , n ] k\in[1,n] k[1,n],进行 b i = ⊕ j = 1 i b j b_i=\oplus_{j=1}^i b_j bi=j=1ibj i ∈ [ 1 , k ] i\in[1,k] i[1,k] 的赋值操作。

为什么这样得到的 b i b_i bi 会等于 a i a_i ai 呢?展开一下就明白了:

b 1 ′ = b 1 b 2 ′ = b 1 ′ ⊕ b 2 b 3 ′ = b 1 ′ ⊕ b 2 ′ ⊕ b 3 b'_1=b_1\\b'_2=b'_1\oplus b_2\\b'_3=b'_1\oplus b'_2\oplus b_3 b1=b1b2=b1b2b3=b1b2b3

如果一项一项带入,就会发现 b i ′ = b i − 1 ⊕ b i b'_i=b_{i-1}\oplus b_i bi=bi1bi。又把 b i b_i bi a i a_i ai 表示,可以得到 b i ′ = ( a 1 ⊕ ⋯ ⊕ a i − 1 ) ⊕ ( a 1 ⊕ ⋯ ⊕ a i ) = a i b'_i=(a_1\oplus\dots\oplus a_{i-1})\oplus (a_1\oplus \dots \oplus a_i)=a_i bi=(a1ai1)(a1ai)=ai

至此,题意与解题目标发生了转化、也更加清晰。

能否构造

观察一手数据范围,可以跑 n log ⁡ b n\log b nlogb。考虑对于每个 i i i,就用 O ( log ⁡ b ) O(\log b) O(logb) 构造出一个 a i a_i ai。这里为了防止前缀和影响已更新好的数,我们选择倒着构造。

先判断能否构造,不难想到,可以构造的充要条件是:每一个 a i a_i ai 都可以由 b [ 1 , i − 1 ] b_{[1,i-1]} b[1,i1] 中的若干数与 b i b_i bi 异或得到。

构造开始

这个 b b b 数组,不是个善茬,想不到怎么很好处理。思考一下 b b b 数组需要做的操作,都是它的线性基可以处理的(其实看到异或问题,多多少少要想到一点线性基)。

我们把基底按先后加入顺序标号,来表示 b b b 的每一个数。此刻来考虑这个新数组 c c c

我们想从 a n ∼ a 1 a_n\sim a_1 ana1 进行构造,如果我们此时构造 a i a_i ai,那么我们不能动 a k a_k ak k ∈ [ i + 1 , n ] k\in[i+1,n] k[i+1,n];否则就打乱了。

所以,当我们改变到第 i i i 位的时候,只能对 k = i k=i k=i 进行操作: b i ← ⊕ j = 1 i b j b_i\leftarrow \oplus_{j=1}^ib_j bij=1ibj。实际上,就是构造异或和等于 a i a_i ai

我们按加入的先后顺序标号,所以当第 i i i 位最早在 p o s i pos_i posi 出现时,在 [ 1 , p o s i − 1 ] [1,pos_i-1] [1,posi1] i i i 这一位都为零。这个很显然。

那得知这个有什么用呢?我们可以通过这个将前缀异或和进行某一位的翻转。既然 p o s i pos_i posi 是第一次出现 i i i,那如果我对 k = p o s i + 1 k=pos_i+1 k=posi+1 进行操作,只有 b p o s i + 1 b_{pos_i+1} bposi+1 的异或和多了 i i i 这一位,总异或和这一位也就可以翻转了。

也是从大到小考虑, p o s i pos_i posi 递减,不会影响之前的数。

构造总结

那现在构造方法就很明了了:

  1. 从大到小枚举 i i i,计算当前异或和。
  2. 当异或和与 a i a_i ai (重标号后的)某一位不一样,就对那一位进行翻转操作。
  3. 最后对 k = m k=m k=m 进行操作,即可得出 a m a_m am
  4. 重复 n n n 遍,最后把操作序列翻转,就是从 a a a b b b 的操作了。

代码

code

#include <bits/stdc++.h>
using namespace std;#define int long longconst int MAXN = 1e3 + 5;int n;
int a[MAXN], b[MAXN], c[MAXN];
int pos[64];
vector<int> ans;struct XXJ {int d[64];  // 基底int id[64], tot;void Clear() {memset(d, 0, sizeof(d));memset(id, 0, sizeof(id));tot = 0;}bool Count(int x) {for (int i = 59; ~i; i--)if (x >> i & 1) {if (d[i] == 0)return 0;x ^= d[i];}return 1;}int Insert(int x) {int res = 0;for (int i = 60; ~i; i--)if (x >> i & 1) {if (d[i] == 0) {d[i] = x;id[i] = tot++;return res | (1ll << id[i]);}res |= (1ll << id[i]);x ^= d[i];}return res;}
} X;void work(int x) {ans.push_back(x);for (int i = 1; i <= x; i++) {b[i] ^= b[i - 1];c[i] ^= c[i - 1];}
}signed main() {scanf("%lld", &n);for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);for (int i = 1; i <= n; i++) scanf("%lld", &b[i]);for (int i = 1; i <= n; i++) {if (X.Count(a[i] ^ b[i]) == 0)return puts("No"), 0;X.Insert(b[i]);}for (int i = n; i; i--) {X.Clear();for (int j = 1; j <= i; j++) {bool flg = X.Count(b[j]);c[j] = X.Insert(b[j]);if (flg == 0)pos[__lg(c[j])] = j;}int tmp = X.Insert(a[i]);for (int j = X.tot; ~j; j--) {int sum = 0;for (int k = 1; k <= i; k++) sum ^= c[k];if ((sum >> j & 1) != (tmp >> j & 1))work(pos[j] + 1);}work(i);}reverse(ans.begin(), ans.end());printf("Yes\n%lld\n", (int)ans.size());for (int i : ans) printf("%lld ", i);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/661904.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Centos7环境安装PHP8

一、安装必要的模块 yum install -y bzip2-devel libcurl-devel libxml2-devel sqlite-devel oniguruma oniguruma-devel libxml2 libxml2-devel bzip2 bzip2-devel libcurl libcurl-devel libjpeg libjpeg-devel zstd libzstd-devel curl libcurl-devel libpng libpng-devel …

AI大模型开发架构设计(8)——从 AI 编程助手到 AI Agent 应用实战

文章目录 从 AI 编程助手到 AI Agent 应用实战1 AI Agent是什么?和AI编程如何协同?AI Agent是什么?AI Agent 案例AI Agent 三种范式AI Agent 和 AI 编程如何协同?2 AGI/LLM/Lightweight AI Agent剖析AGI AgentsLightweight AI Agents3 Lightweight AI Agent技术剖析技术架构…

【日常总结】宝塔中 Gitlab服务器 forbidden

一、场景 二、问题 三、原因 四、解决方案 五、实战 Stage 1&#xff1a;打开 /etc/gitlab/gitlab.rb&#xff0c;并编辑 Stage 2&#xff1a;重启gitlab服务 Stage 3&#xff1a;测试&#xff08;打开girlab网页&#xff09; 六、后续 一、场景 公司更换新电脑 服务…

使⽤COCO数据集训练YOLOX

注意&#xff1a; 训练的时候&#xff0c;如果GPU不够&#xff0c;可以修改batchsize大小。 (yolox) xuefeif123:/mnt/d/BaiduNetdiskDownload/CV/YOLOX$ ls LICENSE README.md assets checkpoints demo exps requirements.txt setup.py tools yolox M…

C语言——P/文件操作

一、为什么使用文件&#xff1f; 如果没有⽂件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运⾏程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进⾏持久…

[Git版本控制系统]

Git是一种版本控制系统&#xff0c;用于跟踪和控制计算机文件的更改。它具有以下几个基本概念&#xff1a; 仓库&#xff08;Repository&#xff09;&#xff1a;Git使用仓库来存储项目的所有文件和历史记录。仓库可以分为本地仓库和远程仓库。本地仓库存在于本地计算机上&…

数据结构—动态查找表

动态查找介绍 1. 动态查找的引入&#xff1a;当查找表以线性表的形式组织时&#xff0c;若对查找表进行插入、删除或排序操作&#xff0c;就必须移动大量的记录&#xff0c;当记录数很多时&#xff0c;这种移动的代价很大。 2. 动态查找表的设计思想&#xff1a;表结构本身是…

web前端开发--------阴影与转换

1.阴影分为文本阴影和盒子阴影 我们使用text-shadow属性为文本添加阴影效果&#xff0c;使用结构伪类为第一个子元素p添加阴影效果&#xff1b; 水平偏移量为负值时&#xff0c;表示阴影向左偏移&#xff1b; &#xfeff;垂直偏移量为负值时&#xff0c;表示阴影向上偏移。 …

【Vue】2-14、插槽 自定义指令

一、插槽 插槽&#xff08;Slot&#xff09;是 vue 为组件的封装者提供的能力。允许封装者在封装组件时&#xff0c;把不确定的&#xff0c;希望由用户指定的部分定义为插槽。 <template><div class"app-container"><h1>App 根组件</h1>&…

【Mysql】数据库架构学习合集

目录 1. Mysql整体架构1-1. 连接层1-2. 服务层1-3. 存储引擎层1-4. 文件系统层 2. 一条sql语句的执行过程2-1. 数据库连接池的作用2-2. 查询sql的执行过程2-1. 写sql的执行过程 1. Mysql整体架构 客户端&#xff1a; 由各种语言编写的程序&#xff0c;负责与Mysql服务端进行网…

go数据操作-elasticsearch

go-elasticsearch是Elasticsearch 官方提供的 Go 客户端。每个 Elasticsearch 版本会有一个对应的 go-elasticsearch 版本。 1.安装依赖 执行以下命令安装v8版本的 go 客户端。 go get github.com/elastic/go-elasticsearch/v8latest导入依赖。 import "github.com/el…

vue学习——elementPlus安装及国际化

引入完整的elementPlus 安装 pnpm i element-plus引入 // main.ts import { createApp } from vue import ElementPlus from element-plus import element-plus/dist/index.css import App from ./App.vueconst app createApp(App)app.use(ElementPlus) app.mount(#app)图标…

JAVA斗地主逻辑-控制台版

未排序版&#xff1a; 准备牌->洗牌 -> 发牌 -> 看牌: App程序入口&#xff1a; package doudihzu01;public class App {public static void main(String[] args) {/*作为斗地主程序入口这里不写代码逻辑*///无参创建对象&#xff0c;作为程序启动new PokerGame();…

大力说视频号第二课:视频号如何挂链接带货

最近&#xff0c;随着视频号带货的风潮&#xff0c;不少小伙伴已经成功跟上潮流&#xff0c;在这个平台上轻松赚取收入。 然而&#xff0c;仍有不少小伙伴对于如何在视频号中挂链接带货感到有些困惑。 目前&#xff0c;视频号的主流带货方式主要分为三种&#xff1a; 01 挂“…

(每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第9章 项目范围管理(四)

博主2023年11月通过了信息系统项目管理的考试&#xff0c;考试过程中发现考试的内容全部是教材中的内容&#xff0c;非常符合我学习的思路&#xff0c;因此博主想通过该平台把自己学习过程中的经验和教材博主认为重要的知识点分享给大家&#xff0c;希望更多的人能够通过考试&a…

回归预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络多变量回归预测

回归预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络多变量回归预测 目录 回归预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-LSTM【24年新算…

QT 范例阅读: undoframework

一、功能 通过给 QGraphicsScene 添加、删除、移动 QGraphicsPolygonItem 来演示 撤销重做功能 标签 undo framework example 二、核心代码&#xff0c;以添加图例为例 MainWindow.cpp 的核心代码 //1 创建堆栈 undoStack new QUndoStack(this); //2 以列表的形式显…

LeetCode第783题 - 二叉搜索树节点最小距离

题目 解答 方案一 class Solution {private List<Integer> values new ArrayList<>();public void inorder(TreeNode node) {if (node null) {return;}inorder(node.left);values.add(node.val);inorder(node.right);}public int minDiffInBST(TreeNode root)…

AI 代码生成

1 csdnC知道 https://so.csdn.net/chat?from_spm1008.2611.3001.9686 2 百度搜索AI伙伴 https://chat.baidu.com/ 3 阿里通义千问 https://tongyi.aliyun.com/qianwen/?spm5176.28326591.0.0.2a8a6ee1TUqfmH //还有的小伙伴们留言,我来整理 //感谢大家的点赞&#xff0c;…

工业自动化中与多台PLC通讯的基本指南

与多台PLC进行通讯是工业自动化中常见的需求。通常&#xff0c;一台THM&#xff08;通常是触摸屏或人机界面&#xff09;会与多台PLC进行通讯&#xff0c;以实现数据交互和控制功能。以下是一个基本的步骤指南&#xff0c;用于实现1台THM与多台PLC的通讯&#xff1a; 确定通讯…