洛谷题单指南-线段树的进阶用法-P4093 [HEOI2016/TJOI2016] 序列

news/2025/1/8 18:04:46/文章来源:https://www.cnblogs.com/jcwy/p/18654873

原题链接:https://www.luogu.com.cn/problem/P4093

题意解读:一个序列,m个变化,求任意一个变化后不受影响的最长上升子序列长度。

解题思路:

设原序列为a[N],原序列经过变化后能得到的最大值序列为maxa[N],最小值序列为mina[N]

设f[i]表示以第i个数结尾的最长不降子序列长度

有f[i] = max(f[j]) + 1,条件是j < i, a[j] <= mina[i], maxa[j] <= a[i]

因此,可以转化为一个三维偏序问题!

借助于树套树,用树状数组套权值线段树,维护对应的位置的最大f值,a,maxa共同代表j

用树状数组维护线段树的根节点root[a[x]],用权值线段树维护maxa[x]对应的maxf值(maxf值就是最大的f[j])

枚举序列,i从1到n

查询已加入树套树的最大f值,也就是查询线段树root[1]~root[a[i]]中值区间<=mina[i]的最大f值,设为res

f[i] = res + 1

然后,将f[i]值更新到root[maxa[i]]~root[MAXA]线段树的值范围包含a[i]的节点的f值,供后面递推查询。

100分代码:

#include <bits/stdc++.h>
using namespace std;const int N = 100005;struct Node
{int L, R;int maxf; //节点表示值域区间[l,r]中最大的f(),也就是以[l,r]中某一个位置的值结尾的最长不降子序列长度
} tr[N * 80];int root[N], idx;
int a[N], maxa[N], mina[N], MAXA; //a:原数组,maxa:a最大可以变成多大,mina:a最小可以变成多小
int f[N]; //f[i]表示以第i个数结尾的最长不降子序列长度
int n, m, ans;int lowbit(int x)
{return x & -x;
}//在根为u的线段树中查询节点值域<=pos的最大的maxf
int query(int u, int l, int r, int pos)
{   if(l == r) return tr[u].maxf;int mid = l + r >> 1;if(pos <= mid) return query(tr[u].L, l, mid, pos);else return max(tr[tr[u].L].maxf, query(tr[u].R, mid + 1, r, pos));
}//将根为u的线段树的值域区间包含pos的节点的maxf值更新(如果v更大的话)
int update(int u, int l, int r, int pos, int v)
{if(!u) u = ++idx;tr[u].maxf = max(tr[u].maxf, v);if(l == r) return u;int mid = l + r >> 1;if(pos <= mid) tr[u].L = update(tr[u].L, l, mid, pos, v);else tr[u].R = update(tr[u].R, mid + 1, r, pos, v);return u;
}//查询maxa[j]<=x且a[j]<=y的j的最大f[j]值
//采用树套树,树状数组维护第一维,权值线段树维护第二维
int find(int x, int y)
{int res = 0;for(int i = x; i; i -= lowbit(i)){res = max(res, query(root[i], 1, MAXA, y));}return res;
}//将x, y对应的maxf更新到树套树
//也就是更新所有root[x]~root[MAXA]的线段树的值为y的节点的maxf为v(如果v更大)
void add(int x, int y, int v)
{for(int i = x; i <= MAXA; i += lowbit(i))root[i] = update(root[i], 1, MAXA, y, v);
}int main()
{cin >> n >> m;for(int i = 1; i <= n; i++) {cin >> a[i];maxa[i] = mina[i] = a[i];}int x, y;while(m--){cin >> x >> y;maxa[x] = max(maxa[x], y);mina[x] = min(mina[x], y);MAXA = max(MAXA, maxa[x]);}for(int i = 1; i <= n; i++){f[i] = find(mina[i], a[i]) + 1; //f[i] = max(f[j]) + 1,j<i, a[j]<=mina[i], maxa[j]<=a[i]add(a[i], maxa[i], f[i]); //将f[i]的值更新到这个j对应树套树中的位置,也就是root[a[i]]~root[MAXA]所有线段树的值maxa[i]的maxf更新为f[i]ans = max(ans, f[i]);}cout << ans;return 0;
}

 

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

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

相关文章

AutoGen入门-让两个AI自行聊天完成任务

AutoGen介绍 AutoGen 是一个开源编程框架,用于构建 AI 代理并促进多个代理之间的合作以解决问题。AutoGen 旨在提供一个易于使用和灵活的框架,以加速代理型 AI 的开发和研究,就像 PyTorch 之于深度学习。它提供了诸如代理之间可以对话、LLM 和工具使用支持、自主和人机协作工…

Centos7 安装redis教程

步骤一:安装gcc依赖检查gcc是否已经安装,命令:gcc -v,出现下图说明已经安装由于 redis 是用 C 语言开发,安装之前必先确认是否安装 gcc 环境(gcc -v),如果没有安装,执行以下命令进行安装yum install -y gcc步骤二:下载redis安装包 https://download.redis.io/relea…

【编码】如何实现一套自定义网络协议?

前言 下文介绍的自定义协议仅作为学习示例,纯粹是玩具项目,没有实际可用性。无需过度关注和讨论其合理性 进行通信的双方是谁? 常见的模型 客户端-服务器,例如HTTP协议,浏览器<=>Web服务器。 中转站模型,如MQTT协议,应用服务<=>中转站<=>硬件客户端 对…

记录一个使用VsCode来ssh的问题(已经打开了ssh的一个文件夹路径,怎么新开一个文件夹路径)

一、操作 使用快捷键 Ctrl+Shift+P(Windows) 或 Cmd+Shift+P (Mac)打开 命令面板 然后输入: File:Open Folder之后就可以选项新的路径打开了。。。没想到我被这个卡了好久,有点无语。

Postman配置接口挡板

0、首先需要在postman上注册并登录账号(登录前最好先备份已有的报文) 如果你在登录后发现历史存储的报文不见了,不要担心,在退出登录后将会重新显示出来。你可以将之前备份的报文导入到登录后的workspace中使用1、进入Workspace,新建Collection 2、找到新建的collection…

vue3新建项目的DevTools Settings

找到vite.config.js 注释掉这两行就消失了

Linux文件系统的安全保障---Overlayroot!

`overlayroot` 是一种使用 OverlayFS 实现的功能,可将根文件系统挂载为只读,并通过一个临时的写层实现对文件系统的修改。这种方法非常适合嵌入式设备或需要保持系统文件完整性和安全性的场景。下文以 RK3568 平台为例,介绍制作 overlayroot 的详细步骤。 ​ 1. 制作精简文件…

DirectX 修复工具 V4.3 绿色增强版:完美解决 DirectX 和 C++ 问题,修复 0xc000007b 错误

介绍 DirectX 修复工具 V4.3 是一款高效的系统修复工具,专为解决 系统异常 和 C++ 运行库 问题而设计,尤其对解决 0xc000007b 错误有着极高的修复率。本工具支持对所有版本的 DirectX 进行修复,并在增强版中新增了对 C++ 运行库问题的修复,提供了一个全面且可靠的解决方案。…

用DevEco Studio模拟器这些能力 没真机也能高效调测鸿蒙原生应用

随着鸿蒙生态的快速发展,越来越多的开发者投身于鸿蒙原生应用的开发中。然而,在实际开发中,真机设备短缺、调测场景复杂等问题常困扰着开发者。为解决这些问题,华为在DevEco Studio上为开发者提供了模拟器(Emulator)功能,帮助开发者在真机匮乏或无真机时,高效且低成本地…

renben-openstack-使用操作

管理员操作 (1)上传一个qcow2格式的centos7镜像 (2)管理员------>云主机类型------>创建云主机类型名称:Centos7VCPU数量:1内存: 1024根磁盘: 10G其他的默认点击创建云主机类型即可界面会显示如下创建公网络 (1)创建公网管理员------>网络------>创建网络…

防护用具穿戴智能监测摄像机

防护用具穿戴智能监测摄像机在现代安全管理中扮演着越来越重要的角色。这些先进设备不仅仅是简单的监视工具,更是通过整合高级技术来提升工作效率和安全性,特别是在复杂环境和危险作业场所的应用日益广泛。防护用具穿戴智能监测摄像机不仅仅是一种安全设备,更是提升工作场所…

场景题:假设有40亿QQ号,但只有1G内存,如何实现去重?

当数据量比较大时,使用常规的方式来判重就不行了。例如,使用 MySQL 数据库判重,或使用 List.contains() 或 Set.contains() 判重就不行了,因为数据量太大会导致内存放不下,或查询速度太慢等问题。 1.空间占用量预测 正常情况下,如果将 40 亿 QQ 号存储在 Java 中的 int 类…