首页 > 其他分享 >洛谷题单指南-线段树的进阶用法-P4093 [HEOI2016/TJOI2016] 序列

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

时间:2025-01-07 17:34:53浏览次数:1  
标签:进阶 int 洛谷题 线段 P4093 mina 序列 maxa root

原题链接: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;
}

 

标签:进阶,int,洛谷题,线段,P4093,mina,序列,maxa,root
From: https://www.cnblogs.com/jcwy/p/18654873

相关文章

  • 【SQL】进阶知识 — 各大数据库合并几条数据到一行的方式
    大家好,欢迎来到本期的SQL知识分享!今天我们要聊一个非常实用的技能:如何将多个行数据合并成一行!如果你曾经需要把多个查询结果合并成一个单元,或者把多行数据汇总到一个字段中,这篇文章将会教你如何用SQL来实现这一点。1.什么是“合并数据到一行”?“合并数据到一行”通常......
  • 如何使用stable diffusion填充画外内容?(进阶版)
    大家好我是AIGC阿道夫目录一、outpaint步骤二、参数详解三、总结当我们尝试绘制高分辨率的图片时,传统的SD模型常常会遇到诸多问题,例如元素重复、显存不足和生成时间过长等。但如果只绘制低分辨率的图片,却很难生成丰富的画面元素和细节。我们可以借助outpaint来解决这......
  • 线段树进阶练习专题
    小白逛公园题目大意:求一段区间里最大子段和思路:有空补(code:#include<bits/stdc++.h>usingnamespacestd;constintMAXN=500100;intm,n;inta[MAXN];inlineintread(){ intx=0,f=1; charch=getchar(); while(ch>'9'||ch<'0'){ if(ch==&#......
  • SQLite 进阶:扩展功能与最佳实践
    在前两篇文章中,我们探讨了SQLite的基础知识和高级功能。本篇将进一步探讨SQLite的扩展功能,包括加密、与其他工具的集成、多线程使用、性能优化,以及如何实现跨平台兼容性。数据加密SQLite本身不直接支持加密,但可以通过SQLite的扩展(如SQLiteEncryptionExtension,......
  • SpringBoot进阶教程(八十四)spring-retry
    在日常的一些场景中,很多需要进行重试的操作.而spring-retry是spring提供的一个基于spring的重试框架,某些场景需要对一些异常情况下的方法进行重试就会用到spring-retry。spring-retry可以帮助我们以标准方式处理任何特定操作的重试。在spring-retry中,所有配置都是基于简单注释......
  • 安全框架SpringSecurity进阶【详解,附有图文+示例代码】
    文章目录十二.SpringSecurity进阶12.1认证流程12.2简单实现(无权限)思路分析准备工作导入依赖添加Redis相关配置Redis使用FastJson序列化RedisCache缓存Redis配置类响应类JWT工具类WebUtils工具类数据库准备实体类yml配置文件实现配置密码加密器12.3自定义登录接口12.......
  • 「Java 数据结构全面解读」:从基础到进阶的实战指南
    「Java数据结构全面解读」:从基础到进阶的实战指南数据结构是程序设计中的核心部分,用于组织和管理数据。Java提供了丰富的集合框架和工具类,涵盖了常见的数据结构如数组、链表、栈、队列和树等。本文将系统性地介绍这些数据结构的概念、特点以及在Java中的实现,并通过代码......
  • 流程控制第二弹: 从小白到高手-Java While 循环的进阶秘籍(文中有福利赠送)
    ......
  • Docker 超强进阶!手把手部署 AllInOne,永久电视直播+自动更新,转载
    1、allinone指令:dockerrun-d--restartunless-stopped--net=host--privileged=true-p35455:35455--nameallinoneyoushandefeiyang/allinone 2、配置watchtower每天凌晨两点自动监听allinone镜像更新指令:dockerrun-d--namewatchtower--restartunless-stopped......
  • ECharts数据可视化:入门、实战与进阶PDF、EPUB免费下载
    适读人群:数据分析师等所有需要制作可视化报表的人员。ECharts官方推荐,系统全面、由浅入深、注重实操,带领读者快速从新人到高手电子版仅供预览,下载后24小时内务必删除,支持正版,喜欢的请购买正版书籍点击原文去下载书籍信息作者:王大伟出版社:机械工业出版社副标题:入......