P9631 [ICPC 2020 Nanjing R] Just Another Game of Stones Solution
Description
给定序列 a = ( a 1 , a 2 , ⋯ , a n ) a=(a_1,a_2,\cdots,a_n) a=(a1,a2,⋯,an),有 m m m 个操作分两种:
- chmax ( l , r , k ) \operatorname{chmax}(l,r,k) chmax(l,r,k):对每个 i ∈ [ l , r ] i \in [l,r] i∈[l,r] 执行 a i ← max ( a i , k ) a_i\gets\max(a_i,k) ai←max(ai,k).
- query ( l , r , k ) \operatorname{query}(l,r,k) query(l,r,k):用石堆 a l ⋯ r a_{l\cdots r} al⋯r 和一堆 k k k 个石子玩
Nim
,求先手第一次取完石子后,后手必败的操作方案数.
Limitations
1 ≤ n , m ≤ 2 × 1 0 5 1 \le n,m \le 2\times 10^5 1≤n,m≤2×105
0 ≤ a i , k < 2 30 0 \le a_i,k < 2^{30} 0≤ai,k<230
1 ≤ l ≤ r ≤ n 1 \le l \le r \le n 1≤l≤r≤n
3 s , 256 MB 3\text{s},256\text{MB} 3s,256MB
Solution
看到 chmax \operatorname{chmax} chmax 先来一个吉司机.
然后看查询,显然要维护 xor \operatorname{xor} xor 和用来判断先手是否必胜.
考虑如何求方案数,将 k k k 算入,设 s s s 为这局游戏的 SG
值,若先手必胜则策略显然为 a i ← a i xor s a_i \gets a_i \operatorname{xor} s ai←aixors,所以把问题转化成求 ∑ [ a i > ( a i xor s ) ] \sum [a_i > (a_i \operatorname{xor} s)] ∑[ai>(aixors)].
考虑异或性质,发现只需要维护某位为 1 1 1 的数的数量,查询时就找到 s s s 最高位,统计这位为 1 1 1 的即可.
需要的信息都可以在吉司机上维护,于是就做完了.
注意 ∞ \infty ∞ 要开够.
Code
4.25 KB , 578 ms , 114.35 MB (in total, C++ 20 with O2) 4.25\text{KB},578\text{ms},114.35\text{MB}\;\texttt{(in total, C++ 20 with O2)} 4.25KB,578ms,114.35MB(in total, C++ 20 with O2)
// Problem: P9631 [ICPC2020 Nanjing R] Just Another Game of Stones
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P9631
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;using i64 = long long;
using ui64 = unsigned long long;
using i128 = __int128;
using ui128 = unsigned __int128;
using f4 = float;
using f8 = double;
using f16 = long double;template<class T>
bool chmax(T &a, const T &b){if(a < b){ a = b; return true; }return false;
}template<class T>
bool chmin(T &a, const T &b){if(a > b){ a = b; return true; }return false;
}const int inf = 2147483647;
struct Node {int l, r;int min, sec, cnt, tag, sum;array<int, 30> bits;
};
using Tree = vector<Node>;
inline int ls(int u) { return 2 * u + 1; }
inline int rs(int u) { return 2 * u + 2; }inline void pushup(Tree& tr, int u) {tr[u].sum = tr[ls(u)].sum ^ tr[rs(u)].sum;if (tr[ls(u)].min == tr[rs(u)].min) {tr[u].min = tr[ls(u)].min;tr[u].cnt = tr[ls(u)].cnt + tr[rs(u)].cnt;tr[u].sec = min(tr[ls(u)].sec, tr[rs(u)].sec);}else if (tr[ls(u)].min < tr[rs(u)].min) {tr[u].min = tr[ls(u)].min;tr[u].cnt = tr[ls(u)].cnt;tr[u].sec = min(tr[ls(u)].sec, tr[rs(u)].min);}else {tr[u].min = tr[rs(u)].min;tr[u].cnt = tr[rs(u)].cnt;tr[u].sec = min(tr[ls(u)].min, tr[rs(u)].sec);}for (int i = 0; i < 30; i++) {tr[u].bits[i] = tr[ls(u)].bits[i] + tr[rs(u)].bits[i];}
}inline void build(Tree& tr, int u, int l, int r, const vector<int>& A) {tr[u].l = l;tr[u].r = r;tr[u].tag = -1;if (l == r) {tr[u].min = tr[u].sum = A[l];tr[u].sec = inf;tr[u].cnt = 1;for (int i = 0; i < 30; i++) tr[u].bits[i] = (A[l] >> i & 1);return;}const int mid = (l + r) >> 1;build(tr, ls(u), l, mid, A);build(tr, rs(u), mid + 1, r, A);pushup(tr, u);
}inline void apply(Tree& tr, int u, int v) {if (tr[u].min >= v) return;tr[u].sum ^= (tr[u].cnt & 1) * (tr[u].min ^ v);for (int i = 0; i < 30; i++)tr[u].bits[i] += ((v >> i & 1) - (tr[u].min >> i & 1)) * tr[u].cnt;tr[u].min = tr[u].tag = v;
}inline void pushdown(Tree& tr, int u) {if (tr[u].tag != -1) {apply(tr, ls(u), tr[u].tag);apply(tr, rs(u), tr[u].tag);tr[u].tag = -1;}
}inline void update(Tree& tr, int u, int l, int r, int v) {if (tr[u].min >= v) return;if (l <= tr[u].l && tr[u].r <= r && tr[u].sec > v) return apply(tr, u, v);const int mid = (tr[u].l + tr[u].r) >> 1;pushdown(tr, u);if (l <= mid) update(tr, ls(u), l, r, v);if (r > mid) update(tr, rs(u), l, r, v);pushup(tr, u);
}inline int qsum(Tree& tr, int u, int l, int r) {if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum;const int mid = (tr[u].l + tr[u].r) >> 1;pushdown(tr, u);if (r <= mid) return qsum(tr, ls(u), l, r);else if (l > mid) return qsum(tr, rs(u), l, r);else return qsum(tr, ls(u), l, r) ^ qsum(tr, rs(u), l, r);
}inline int qbit(Tree& tr, int u, int l, int r, int k) {if (l <= tr[u].l && tr[u].r <= r) return tr[u].bits[k];const int mid = (tr[u].l + tr[u].r) >> 1;pushdown(tr, u);if (r <= mid) return qbit(tr, ls(u), l, r, k);else if (l > mid) return qbit(tr, rs(u), l, r, k);else return qbit(tr, ls(u), l, r, k) + qbit(tr, rs(u), l, r, k);
}signed main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int n, m;scanf("%d %d", &n, &m);vector<int> a(n);for (int i = 0; i < n; i++) scanf("%d", &a[i]);Tree tr(n << 2);build(tr, 0, 0, n - 1, a);auto get = [&](int l, int r, int x) {int sg = qsum(tr, 0, l, r) ^ x, bit = -1;for (int i = 0; i < 30; i++)if (sg >> i & 1) bit = i;if (bit == -1) return 0;return qbit(tr, 0, l, r, bit) + (x >> bit & 1);};for (int i = 0, op, l, r, v; i < m; i++) {scanf("%d %d %d %d", &op, &l, &r, &v);l--, r--;if (op == 1) update(tr, 0, l, r, v);else printf("%d\n", get(l, r, v));}return 0;
}
相关文章:
P9631 [ICPC 2020 Nanjing R] Just Another Game of Stones Solution
Description 给定序列 a ( a 1 , a 2 , ⋯ , a n ) a(a_1,a_2,\cdots,a_n) a(a1,a2,⋯,an),有 m m m 个操作分两种: chmax ( l , r , k ) \operatorname{chmax}(l,r,k) chmax(l,r,k):对每个 i ∈ [ l , r ] i \in [l,r] i∈[l,…...

nodejs:vue 3 + vite 作为前端,将 html 填入<iframe>,在线查询英汉词典
向 doubao.com/chat/ 提问: node.js js-mdict 作为后端,vue 3 vite 作为前端,编写在线查询英汉词典 后端部分(express js-mdict ) 详见上一篇:nodejs:express js-mdict 作为后端ÿ…...
QEMU源码全解析 —— 内存虚拟化(18)
接前一篇文章:QEMU源码全解析 —— 内存虚拟化(17) 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM源码解析与应用》 —— 李强,机械工业出版社 QEMU内存管理模型...

Spring Boot 日志管理(官网文档解读)
摘要 本篇文章详细介绍了SpringBoot 日志管理相关的内容,文章主要参考官网文章的描述内容,并在其基础上进行一定的总结和拓展,以方便学习Spring Boot 的小伙伴能快速掌握Spring Boot 日志管理相关的内容。 日志实现方式 Sping Boot 的日志管…...
MATLAB进阶之路:数据导入与处理
在MATLAB的学习旅程中,我们已经初步了解了它的基础操作。如今,我们将沿着这条充满惊喜的道路,迈向下一个重要的站点——数据导入与处理。这部分内容就像是为MATLAB注入了强大的能量,使其能够从现实的数据世界中汲取信息,然后像一位智慧的魔法师一样,巧妙地处理这些数据,…...
fcntl()函数的概念和使用案例 c语言
在 Linux 系统编程中,fcntl() 函数(File Control)是用于操作文件描述符的核心函数,可控制文件或套接字的底层属性。它支持多种操作,包括设置非阻塞模式、获取/设置文件状态标志、管理文件锁等。以下是详细概念和使用案…...

Linux红帽:RHCSA认证知识讲解(一)RedHat背景与环境配置
Linux红帽:RHCSA认证知识讲解(一)RedHat背景与环境配置 前言一、RedHat公司背景二、RedHat环境安装步骤三、windows使用远程工具连接环境并上传文件到redhat方法: 前言 在接下来的博客中,我们从基础开始将介绍红帽Linu…...

Windows11安装GPU版本Pytorch2.6教程
1: 准备工作 针对已经安装好的Windows11系统,先检查Nvidia驱动和使用的CUDA版本情况。先打开Windows PowerShell,通过nvidia-smi命令查看GPU的情况,结果如下图1所示,从结果中可知使用的CUDA版本为12.8。 图1:检测安装…...
网络传输的七层协议
网络传输的七层协议是 OSI模型(开放系统互联模型) 中的七个层次,每一层都负责不同的网络功能。具体如下: 物理层(Physical Layer) 负责在物理媒介上传输比特流,即将数据以电信号、光信号等形式在…...
【蓝桥杯集训·每日一题2025】 AcWing 6134. 哞叫时间II python
6134. 哞叫时间II Week 1 2月20日 农夫约翰正在试图向埃尔茜描述他最喜欢的 USACO 竞赛,但她很难理解为什么他这么喜欢它。 他说「竞赛中我最喜欢的部分是贝茜说『现在是哞哞时间』并在整个竞赛中一直哞哞叫」。 埃尔茜仍然不理解,所以农夫约翰将竞赛…...
Spring Boot数据访问(JDBC)全解析:从基础配置到高级调优
文章目录 引言一、Spring Boot JDBC核心架构1.1 核心组件关系图1.2 自动配置逻辑 二、基础配置实践2.1 数据源配置2.2 多数据源配置 三、JdbcTemplate深度使用3.1 基础CRUD操作3.2 批处理优化 四、事务管理4.1 声明式事务4.2 事务传播机制 五、异常处理5.1 Spring异常体系5.2 自…...
三数之和:经典问题的多种优化策略
三数之和:经典问题的多种优化策略 大家好,我是Echo_Wish。今天我们来聊一个经典的算法问题——三数之和(3Sum)。它是许多面试和算法竞赛中常见的问题之一,也常常考察我们对算法优化的理解和技巧。我们不仅要解决问题&…...
信息学奥赛一本通 1520:【 例 1】分离的路径 | 洛谷 P2860 [USACO06JAN]Redundant Paths G
【题目链接】 ybt 1520:【 例 1】分离的路径 洛谷 P2860 [USACO06JAN]Redundant Paths G 【题目考点】 1. 图论:割边(桥) 边双连通分量 【解题思路】 每个草场是一个顶点,草场之间的双向路是无向边,该…...

架构师面试(六):熔断和降级
问题 在千万日活的电商系统中,商品列表页服务通过 RPC 调用广告服务;经过统计发现,在最近10秒的时间里,商品列表页服务在对广告服务的调用中有 98% 的调用是超时的; 针对这个场景,下面哪几项的说法是正确的…...

使用 DeepSeek 生成流程图、甘特图与思维导图:结合 Typora 和 XMind 的高效工作流
在现代工作与学习中,可视化工具如流程图、甘特图和思维导图能够极大地提升信息整理与表达的效率。本文将详细介绍如何使用 DeepSeek 生成 Mermaid 文本,结合 Typora 快速生成流程图和甘特图,并通过 Markdown 格式生成思维导图,最终…...
粘贴到Word里的图片显示不全
粘贴到Word里的图片显示不全,可从Word设置、图片本身、软件与系统等方面着手解决,具体方法如下: Word软件设置 经实践发现,图片在word行距的行距出现问题,可以按照如下调整行距进行处理 修改段落行距: 选…...

【C语言】结构体内存对齐问题
1.结构体内存对齐 我们已经基本掌握了结构体的使用了。那我们现在必须得知道结构体在内存中是如何存储的?内存是如何分配的?所以我们得知道如何计算结构体的大小?这就引出了我们今天所要探讨的内容:结构体内存对齐。 1.1 对齐规…...

【蓝桥杯单片机】第十三届省赛第二场
一、真题 二、模块构建 1.编写初始化函数(init.c) void Cls_Peripheral(void); 关闭led led对应的锁存器由Y4C控制关闭蜂鸣器和继电器 2.编写LED函数(led.c) void Led_Disp(unsigned char ucLed); 将ucLed取反的值赋给P0 开启锁存器 关闭锁存…...
类与对象(5)
上一章是类与对象(4)-CSDN博客 深入了构造函数和静态成员,大概讲解了类型转换 最后一章最后一章 友元 在 C 中,友元提供了一种突破类的访问控制(封装)的方式。通过友元,外部的函数或类可以访…...
AI知识架构之数据采集
数据采集 数据格式: 结构化数据:以固定格式和结构存储,如数据库中的表以及 Excel 表格,易于查询和分析。半结构化数据:有一定结构但不如结构化数据严格,XML 常用于数据交换,JSON 在 Web 应用中广泛用于数据传输和存储。非结构化数据:无预定义结构,文本、图像、音频和视…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...