详细介绍:进阶数据结构Splay应用-维护数列

news/2026/1/20 10:42:30/文章来源:https://www.cnblogs.com/yangykaifa/p/19505288

引言

该问题几乎包含了所有的splaysplaysplay操作, 假设不了解splaysplaysplay可以单击这里

题目-维护数列

问题分析

因为涉及到区间翻转操作, 线段树无法实现(线段树解决的是区间属性问题)

其实最复杂的操作是求区间的最大
子段和
, 可以考虑splaysplaysplay维护的节点信息

splaysplaysplay每个节点表示一个数字, 多个点构成的的中序遍历就是希望求的序列, 因此序列就是中序遍历维护的

算法步骤

splaysplaysplay维护的节点信息

  • 维护最大子段和,maxv,lm,rm,summaxv, lm, rm, summaxv,lm,rm,sum
  • 节点儿子, 父节点信息s,ps, ps,p, 当前节点的权值vvv
  • 是否翻转revrevrev
  • 查询节点的前驱和后继cntcntcnt
  • 整个区间是否变成相同的数samesamesame

实现细节

如果一个点有延迟标记, 这个点的权值存储的是执行延迟标记之前的值还是执行延迟标记之后的值需要自己去定义

因为执行samesamesame或者revrevrev延迟标记, 会对当前节点的值(maxv,lm,rm,summaxv, lm, rm, summaxv,lm,rm,sum)产生影响, 能够定义当前节点的值(maxv,lm,rm,summaxv, lm, rm, summaxv,lm,rm,sum)是延迟标记操作之后的值

具体的来说

对于当前节点, 如果打上了延迟标记, 那么将该节点的maxv,lm,rm,summaxv, lm, rm, summaxv,lm,rm,sum都计算一遍


并且在节点执行push down延迟操作的时候, 不仅仅是直接将子节点打上标记, 而且将子节点的maxv,lm,rm,summaxv, lm, rm, summaxv,lm,rm,sum计算一遍

在删除过程中需要进行内存回收优化内存将删除的节点就是, 也就回收到节点池

因此初始化的时候, ms = sum = v, 不能是max(v, 0)

代码实现

注意事项:

  • 计算跨区间的情况, 需要加当前节点的值vvv
  • 注意内存池的指针变量不要和父节点变量ppp重名
  • 因为有哨兵节点的存在, 注意get_k()的参数
  • 延迟标记的处理, 规定若是当前对某个子树打上延迟标记, 对于当前节点立刻生效
  • 题目要求最大子段和最少囊括一个点, 因此初始化ms的时候, 不能设置为max⁡(v,0)\max(v, 0)max(v,0), 而是没有选择的设置为vvv
  • 000号点是边界哨兵节点, 因此初始化节点池的时候, 必须从111开始
#include <bits/stdc++.h>using namespace std;const int N = 5e5 + 10, INF = 1e9;int n, m;struct Node {int s[2], p, v;int rev, same, cnt;int ms, ls, rs, sum;// 因为内存回收机制的存在, 必须在此刻重置rev和same的延迟标记void init(int _v, int _p) {s[0] = s[1] = 0;p = _p, v = _v;cnt = 1;rev = same = 0;sum = ms = v;ls = rs = max(v, 0);}} tr[N];// nodes作为节点池, ptr分配节点int root, nodes[N], ptr;int w[N];void pushup(int u) {Node &lson = tr[tr[u].s[0]], &rson = tr[tr[u].s[1]];tr[u].cnt = lson.cnt + rson.cnt + 1;tr[u].sum = lson.sum + rson.sum + tr[u].v;tr[u].ls = max(lson.ls, lson.sum + tr[u].v + rson.ls);tr[u].rs = max(rson.rs, rson.sum + tr[u].v + lson.rs);// 注意需要加当前节点的值tr[u].ms = max({lson.ms, rson.ms, lson.rs + tr[u].v + rson.ls});}void pushdown(int u) {Node &lson = tr[tr[u].s[0]], &rson = tr[tr[u].s[1]];if (tr[u].same) {tr[u].same = tr[u].rev = 0;if (tr[u].s[0]) {lson.same = 1;lson.v = tr[u].v;lson.sum = tr[u].v * lson.cnt;if (tr[u].v > 0) lson.ms = lson.ls = lson.rs = lson.sum;else {lson.ms = tr[u].v;lson.ls = lson.rs = 0;}}if (tr[u].s[1]) {rson.same = 1;rson.v = tr[u].v;rson.sum = tr[u].v * rson.cnt;if (tr[u].v > 0) rson.ms = rson.ls = rson.rs = rson.sum;else {rson.ms = tr[u].v;rson.ls = rson.rs = 0;}}}// 当子树的根被打上标记, 约定翻转, 这里就不需要翻转else if (tr[u].rev) {tr[u].rev = 0;lson.rev ^= 1, rson.rev ^= 1;swap(lson.ls, lson.rs), swap(rson.ls, rson.rs);swap(lson.s[0], lson.s[1]), swap(rson.s[0], rson.s[1]);}}void rotate(int x) {int y = tr[x].p, z = tr[y].p;int k = tr[y].s[1] == x;tr[z].s[tr[z].s[1] == y] = x, tr[x].p = z;tr[y].s[k] = tr[x].s[k ^ 1], tr[tr[x].s[k ^ 1]].p = y;tr[x].s[k ^ 1] = y, tr[y].p = x;pushup(y), pushup(x);}void splay(int x, int k) {while (tr[x].p != k) {int y = tr[x].p, z = tr[y].p;if (z != k) {if ((tr[z].s[1] == y) ^ (tr[y].s[1] == x)) rotate(x);else rotate(y);}rotate(x);}if (!k) root = x;}// 将一段序列构建二叉树int build(int l, int r, int p) {int mid = l + r >> 1;int u = nodes[ptr--];tr[u].init(w[mid], p);if (l < mid) tr[u].s[0] = build(l, mid - 1, u);if (r > mid) tr[u].s[1] = build(mid + 1, r, u);pushup(u);return u;}int get_k(int k) {int u = root;while (u) {pushdown(u);int cnt = tr[tr[u].s[0]].cnt + 1;if (cnt > k) u = tr[u].s[0];else if (cnt == k) return u;else u = tr[u].s[1], k -= cnt;}return 0;}// 内存回收void release(int u) {if (tr[u].s[0]) release(tr[u].s[0]);if (tr[u].s[1]) release(tr[u].s[1]);nodes[++ptr] = u;}int main() {ios::sync_with_stdio(false);cin.tie(0);// 所有点是可用的for (int i = 1; i < N; ++i) nodes[++ptr] = i;cin >> n >> m;for (int i = 1; i <= n; ++i) cin >> w[i];// 为了保证数列时刻都有数字以及如果当前节点没有左右儿子节点不会造成影响tr[0].ms = w[0] = w[n + 1] = -INF;// 原序列初始化为树root = build(0, n + 1, 0);string op;while (m--) {cin >> op;if (op == "INSERT") {int posi, tot;cin >> posi >> tot;int u = get_k(posi + 1), v = get_k(posi + 2);splay(u, 0), splay(v, u);for (int i = 0; i < tot; ++i) cin >> w[i];tr[v].s[0] = build(0, tot - 1, v);pushup(v), pushup(u);}else if (op == "DELETE") {int posi, tot;cin >> posi >> tot;int u = get_k(posi), v = get_k(tot + posi + 1);splay(u, 0), splay(v, u);release(tr[v].s[0]);tr[v].s[0] = 0;pushup(v), pushup(u);}else if (op == "MAKE-SAME") {int posi, tot, c;cin >> posi >> tot >> c;int u = get_k(posi), v = get_k(tot + posi + 1);splay(u, 0), splay(v, u);Node &son = tr[tr[v].s[0]];son.same = 1;son.v = c;son.sum = son.cnt * c;if (c > 0) son.ms = son.ls = son.rs = son.sum;else {son.ms = c;son.ls = son.rs = 0;}pushup(v), pushup(u);}else if (op == "REVERSE") {int posi, tot;cin >> posi >> tot;int u = get_k(posi), v = get_k(tot + posi + 1);splay(u, 0), splay(v, u);Node &son = tr[tr[v].s[0]];son.rev ^= 1;swap(son.ls, son.rs);swap(son.s[0], son.s[1]);pushup(v), pushup(u);}else if (op == "GET-SUM") {int posi, tot;cin >> posi >> tot;int u = get_k(posi), v = get_k(tot + posi + 1);splay(u, 0), splay(v, u);cout << tr[tr[v].s[0]].sum << '\n';pushup(v), pushup(u);}else {cout << tr[root].ms << '\n';}}return 0;}

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

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

相关文章

Python 流程控制详解:条件语句 + 循环语句 + 人生重开模拟器实战

Python 流程控制详解 Python 中的流程控制是编程的基础&#xff0c;它允许程序根据条件或重复执行某些代码块。主要包括条件语句&#xff08;if、elif、else&#xff09;和循环语句&#xff08;for、while&#xff09;。下面我将一步步详解它们&#xff0c;并通过示例说明。最…

springboot高校学习讲座预约管理系统设计实现

高校学习讲座预约管理系统的背景高校作为知识传播和学术交流的重要场所&#xff0c;频繁举办各类学术讲座、专家报告等活动。传统讲座管理多依赖人工登记、纸质签到或简单电子表格&#xff0c;存在信息滞后、资源分配不均、学生参与度低等问题。随着高校规模扩大和信息化需求提…

hive 小文件优化

想了解 Hive 小文件的优化方案,小文件会给 Hive 带来诸多负面影响(如占用过多 NameNode 内存、降低查询执行效率、增加任务调度开销等),优化需从事前预防、事后治理、配置优化三个核心维度入手,以下是全面且可落地…

Java核心语法:从变量到流程控制

Java 的核心语法是学习 Java 编程的起点&#xff0c;主要包括变量与数据类型、运算符、流程控制&#xff08;条件判断 循环&#xff09;等基础内容。下面从最基础的部分开始&#xff0c;系统地讲解这些核心语法&#xff0c;并配以清晰的示例和流程图参考。 1. 变量与数据类型…

springboot攻防靶场实验室平台的设计与实现

背景与意义 SpringBoot攻防靶场实验室平台的设计与实现&#xff0c;源于网络安全领域对实战化训练环境的迫切需求。随着网络攻击手段的多样化和复杂化&#xff0c;传统的理论教学已无法满足安全人才培养的需求&#xff0c;亟需一个高度仿真、可交互的实践平台。 技术背景 Spr…

如何轻松将 Python 英文版切换至中文界面

Python 的“英文版”切换到中文界面&#xff0c;主要取决于你指的到底是哪个部分&#xff1a; Python 解释器 / 命令行&#xff1a;本身没有界面语言概念&#xff08;一直是英文提示&#xff09;&#xff0c;但错误信息、帮助文档可以看中文版。IDLE&#xff08;Python 自带的…

元宇宙:数字文明的下一站

一、元宇宙的起源与演进&#xff1a;从科幻概念到科技浪潮元宇宙的概念最早可追溯至1992年——美国作家尼尔斯蒂芬森在科幻小说《雪崩》中首次提出“Metaverse”一词&#xff0c;描绘了一个与现实世界平行的虚拟空间&#xff0c;人们通过数字化身在其中生活、交互。这一设想随后…

物联网 (IoT) 助力您提升业务的 9 种方式

物联网&#xff08;IoT&#xff09;本质上是一个由互联设备构成的网络&#xff0c;这些设备能够跨网络收集并传输数据。 传感器、通信设备与身份识别芯片持续与云端及数据分析引擎交互&#xff0c;推动企业迈入自动化新时代。物联网能够为各规模企业提供实时反馈&#xff0c;助…

Delphi 与 VS 调试快捷键精准对应表

梳理Delphi和Visual Studio中调试相关快捷键的对应关系,这样在从Delphi切换到VS调试代码时,能快速匹配熟悉的操作习惯,不用反复记忆新的快捷键组合。下面我会按调试操作的核心场景分类,清晰列出两者的快捷键对应关…

硅基计划4.0 算法 递归回溯 - 实践

硅基计划4.0 算法 递归&回溯 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mo…

如何为制造业选geo优化公司?2026年geo优化公司全面评测与推荐,直击精准询盘痛点 - 品牌推荐

基于《2026年中国企业AI搜索生态应用趋势报告》核心洞察、行业权威技术认证及第三方实测数据,甄选出2026年值得合作的GEO优化服务商榜单,覆盖高端制造、专业服务、知识内容、工业B2B等多种行业需求,逐一解答“哪家G…

钱包技术:从私钥保管到Web3入口的演进之路

在区块链世界中&#xff0c;钱包不仅仅是存储数字货币的地方&#xff0c;更是用户与整个去中心化网络交互的入口。它经历了从简单的密钥管理工具到多功能数字资产控制中心的演变&#xff0c;成为Web3生态的核心基础设施。一、钱包技术的发展历程早期单链时代&#xff08;2009-2…

EI会议推荐!2026年机器视觉、检测与三维成像技术国际学术会议(MVDIT 2026)

会议官网&#xff1a;https://www.yanfajia.com/action/p/QHT2TU33 会议日期&#xff1a; 2026年5月15-17日 会议地点&#xff1a;中国 南昌 接受或拒绝通知日期&#xff1a;提交后7个工作日 检索类型&#xff1a;EI Compendex、Scopus 会议秘书&#xff1a;Julian 联系电…

数据安全有保障的BI产品?观远数据筑牢企业核心资产防护墙 - 速递信息

在数据驱动的商业时代,数据安全已成为企业数字化转型的生命线。BI 产品作为整合、分析、呈现企业核心数据的关键工具,其数据安全保障能力直接决定企业数据资产是否面临泄露、篡改、丢失等风险。对于金融、央国企、零…

单北斗GNSS变形监测系统是什么?主要应用于水库和桥梁形变监测吗?

单北斗GNSS变形监测系统作为一种高效的监测工具&#xff0c;广泛应用于水库和桥梁等基础设施的形变监测。它利用北斗卫星信号&#xff0c;实时获取结构的微小变形数据&#xff0c;为工程安全提供可靠依据。在这些应用中&#xff0c;系统能够自动化记录和分析监测数据&#xff0…

操作系统进程间通信(IPC)的庖丁解牛

操作系统进程间通信&#xff08;IPC, Inter-Process Communication&#xff09;是 多进程系统中协调、同步与数据交换的核心机制。它解决了 进程隔离性 与 协作需求 之间的根本矛盾。理解 IPC&#xff0c;是掌握高并发、分布式系统、安全模型的基石。一、为什么需要 IPC&#x…

2026年GEO优化公司推荐:针对知识密集型行业痛点排名,涵盖法律与教育多场景应用 - 品牌推荐

由中国领先的行业监测与权威平台《广告主评论》主办、中经总网中经在线(全称中国经济报道)、世界品牌研究院(中国)集团有限公司协办支持的“全球 GEO 厂商评测”,从 GEO 理论奠基、技术实践、创始人背景、技术资质…

springboot高等数学课程教辅资源系统的设计与实现

高等数学课程教辅资源系统的背景高等数学是理工科专业的基础课程&#xff0c;内容涵盖微积分、线性代数、概率统计等&#xff0c;理论性强且抽象。传统教学模式下&#xff0c;学生常面临知识点理解困难、习题资源分散、个性化学习支持不足等问题。SpringBoot作为轻量级Java框架…

EI往届检索稳定JPCS出版| 往届检索可查 | 第四届机械工程与先进制造智能化技术研讨会(MEAMIT 2026)

高录用&#xff5c;EI 稳定检索&#xff5c; 学生投稿优惠 在线征集&#xff1a;机械工程、先进制造技术、智能制造系统与自动化 机器人及协作系统、智能检测与质量控制、先进加工与增材制造等相关主题稿件 欢迎团体投稿/参会&#xff0c;享专属优惠&#xff01;详情请咨询大…

springboot高校党员信息管理系统

高校党员信息管理系统的背景高校党员信息管理系统是针对高校党组织管理需求开发的数字化平台。高校党员群体具有流动性强、信息更新频繁的特点&#xff0c;传统纸质档案或分散的电子表格管理方式效率低下&#xff0c;难以满足党员发展、组织关系转接、党费收缴等工作的精准化需…