线段树 区间赋值 + 区间加减 + 求区间最值

news2024/10/6 7:08:00

线段树好题:P1253 扶苏的问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

区间赋值 + 区间加减 + 求区间最大。

对于区间赋值和区间加减来说,需要两个懒标记,一个表示赋值cover,一个表示加减add

区间赋值的优先级大于区间加减。

对于区间赋值来说,需要将区间加减的标记重置,因为赋值完后,之前的区间加减队现在的值没有影响。

void coverdown(int u) {
    auto &root = tr[u], &right = tr[rs(u)], &left = tr[ls(u)];
    if(root.cover != -INF) {
        left.add = right.add = 0;
        left.ma = right.ma = root.cover;
        left.cover = right.cover = root.cover;
        root.cover = -INF;
    }
}

对于区间加减来说,需要先用区间赋值得到最新的值,之后再进行加减操作。

void sumdown(int u) {
    auto &root = tr[u], &right = tr[rs(u)], &left = tr[ls(u)];
    if(root.add) {
        coverdown(u);
        left.ma += root.add; right.ma += root.add;
        left.add += root.add; right.add += root.add;
        root.add = 0;
    }    
}

线段树中一般的pushdown的顺序不变,但是在pushdown函数中,需要先执行coverdown再执行sumdown。

void pushdown(int u) {
    coverdown(u); sumdown(u);
}

区间加减时,只需要先进行区间赋值就行。

void modify_add(int u, int l, int r, int d) {
    if(tr[u].l >= l && tr[u].r <= r) {
        coverdown(u);
        tr[u].ma += d;
        tr[u].add += d;
    }
    else {
        pushdown(u);
        int mid = tr[u].l + tr[u].r >> 1;
        if(l <= mid) modify_add(ls(u), l ,r, d);
        if(r > mid) modify_add(rs(u), l, r, d);
        pushup(u);
    }
}

区间赋值时,需要先将区间加减懒标记重置,其他一样。

void modify_cover(int u, int l, int r, int d) {
    if(tr[u].l >= l && tr[u].r <= r) {
        tr[u].add = 0;
        tr[u].ma = d;
        tr[u].cover = d;
    } else {
        pushdown(u);
        int mid = tr[u].l + tr[u].r >> 1;
        if(l <= mid) modify_cover(ls(u), l, r, d);
        if(r > mid) modify_cover(rs(u), l, r, d);
        pushup(u);
    }
}

AC代码:

#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <queue>
#include <ctime>
#include <random>
#include <sstream>
#include <numeric>
#include <stdio.h>
#include <functional>
#include <bitset>
#include <algorithm>
using namespace std;

// #define Multiple_groups_of_examples
#define int_to_long_long
#define IOS std::cout.tie(0);std::cin.tie(0)->sync_with_stdio(false);
#define dbgnb(a) std::cout << #a << " = " << a << '\n';
#define dbgtt cout<<" !!!test!!! "<<endl;
#define rep(i,x,n) for(int i = x; i <= n; i++)

#define all(x) (x).begin(),(x).end()
#define pb push_back
#define vf first
#define vs second

typedef long long LL;
#ifdef int_to_long_long
#define int long long
#endif
typedef pair<int,int> PII;

const int INF = 1e18;
const int N = 1e6 + 21;


// 当输入数据大于 1e6 时用快读
inline int fread() // 快读
{
    int x = 0, f = 1; char ch = getchar();
    while(ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') {
        x = x * 10 + (ch - '0');
        ch = getchar();
    }
    return x * f;
}

int w[N],n,m; // 注意 w[N] 开LL ( https://www.luogu.com.cn/problem/P2357
struct adt {
    int l,r;
    int ma,add,cover;
}tr[N << 2];
// 左子树
inline int ls(int p) {return p<<1; }
// 右子树
inline int rs(int p) {return p<<1|1; }
// 向上更新
void pushup(int u) {
    tr[u].ma = max(tr[ls(u)].ma, tr[rs(u)].ma);
}

void coverdown(int u) {
    auto &root = tr[u], &right = tr[rs(u)], &left = tr[ls(u)];
    if(root.cover != -INF) {
        left.add = right.add = 0;
        left.ma = right.ma = root.cover;
        left.cover = right.cover = root.cover;
        root.cover = -INF;
    }
}
void sumdown(int u) {
    auto &root = tr[u], &right = tr[rs(u)], &left = tr[ls(u)];
    if(root.add) {
        coverdown(u);
        left.ma += root.add; right.ma += root.add;
        left.add += root.add; right.add += root.add;
        root.add = 0;
    }    
}
void pushdown(int u) {
    coverdown(u); sumdown(u);
}
// 建树
void build(int u, int l, int r) {
    if(l == r) tr[u] = {l, r, w[r], 0, -INF};
    else {
        tr[u] = {l,r, 0, 0, -INF}; // 容易忘
        int mid = l + r >> 1;
        build(ls(u), l, mid), build(rs(u), mid + 1, r);
        pushup(u);
    }
}
// 修改
void modify_add(int u, int l, int r, int d) {
    if(tr[u].l >= l && tr[u].r <= r) {
        coverdown(u);
        tr[u].ma += d;
        tr[u].add += d;
    }
    else {
        pushdown(u);
        int mid = tr[u].l + tr[u].r >> 1;
        if(l <= mid) modify_add(ls(u), l ,r, d);
        if(r > mid) modify_add(rs(u), l, r, d);
        pushup(u);
    }
}
void modify_cover(int u, int l, int r, int d) {
    if(tr[u].l >= l && tr[u].r <= r) {
        tr[u].add = 0;
        tr[u].ma = d;
        tr[u].cover = d;
    } else {
        pushdown(u);
        int mid = tr[u].l + tr[u].r >> 1;
        if(l <= mid) modify_cover(ls(u), l, r, d);
        if(r > mid) modify_cover(rs(u), l, r, d);
        pushup(u);
    }
}
// 查询
LL query(int u, int l, int r) {
    if(tr[u].l >= l && tr[u].r <= r) {
        return tr[u].ma;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    LL res = -INF;
    if(l <= mid) res = query(ls(u), l, r);
    if(r > mid ) res =max(res, query(rs(u), l, r));
    return res;
}

void inpfile();
void solve() {
    int n,q; cin>>n>>q;
    for(int i = 1; i <= n; ++i) w[i] = fread();
    build(1,1,n);
    while(q--) {
        // int opt,l,r,x; cin>>opt>>l>>r;
        int opt = fread(), l = fread(), r = fread();
        if(opt == 1) {
            // cin>>x;
            int x = fread();
            modify_cover(1,l,r,x);
        } else if(opt == 2) {
            // cin>>x;
            int x = fread();
            modify_add(1,l,r,x);
        } else {
            cout<<query(1,l,r)<<'\n';
        }
    }
}
#ifdef int_to_long_long
signed main()
#else
int main()
#endif

{
    #ifdef Multiple_groups_of_examples
    int T; cin>>T;
    while(T--)
    #endif
    solve();
    return 0;
}
void inpfile() {
    #define mytest
    #ifdef mytest
    freopen("ANSWER.txt", "w",stdout);
    #endif
}

记录详情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

在这里插入图片描述

P1253 扶苏的问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

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

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

相关文章

LeetCode热题100 旋转图像

题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9…

安全架构的设计理论与实践

安全架构的设计理论与实践 安全架构概述 信息安全面临的威胁 安全架构的定义和范围 信息安全相关的国内外标准及组织 主要安全模型 状态机模型(BLP)模型 Bell-IaPadula模型 Biba模型 Clark-Wilson (CWM)模型 ChineseWall模型 系统安全体系架构规划框架 安全技术体系架构 信息系…

计算机毕业设计选题推荐-流浪动物救助微信小程序/安卓APP-项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

java try throw exception finally 遇上 return break continue造成异常丢失

如下所示&#xff0c;是一个java笔试题&#xff0c;考察的是抛出异常之后&#xff0c;程序运行结果&#xff0c;但是这里抛出异常&#xff0c;并没有捕获异常&#xff0c;而是通过finally来进行了流程控制处理。 package com.xxx.test;public class ExceptionFlow {public sta…

一周通过Professional Scrum Master(PSM1)考试准备分享

目录 一、为什么要考PSM 二、考试培训费用 三、学习时间 四、备考流程 1.通读Scrum Guide 2.完成Scrum Open的练习题3次 3.找题库刷题 4.再次完成Scrum Open的练习题3次 5.正式参加考试 五、其他考试准备 1.考试资格购买 2.语言 六、后记 一、为什么要考PSM 市面上有不少…

设计模式—创建型模式之原型模式

设计模式—创建型模式之原型模式 原型模式&#xff08;Prototype Pattern&#xff09;用于创建重复的对象&#xff0c;同时又能保证性能。 本体给外部提供一个克隆体进行使用。 比如我们做一个SjdwzMybatis&#xff0c;用来操作数据库&#xff0c;从数据库里面查出很多记录&…

vue3后台管理框架之将模拟Mock接口替换成真实接口

首先配置跨域代理 替换接口 由于请求数据格式是表单格式 我们需要下载qs 件请求数据序列化变成表单格式 安装依赖 pnpm i qs 引入 import * as qs from qs //统一管理咱们项目用户相关的接口 import * as qs from qs import request from /utils/requestimport type { login…

【java学习—十】抛出异常(3)

文章目录 1. 声明抛出异常2. 重写方法声明抛出异常的原则3. 人工抛出异常4. 创建用户自定义异常类 1. 声明抛出异常 声明抛出异常是 Java 中处理异常的第二种方式&#xff1a; • 如果一个方法 ( 中的语句执行时 ) 可能生成某种异常&#xff0c;但是并不能确定如何处理这种异常…

目标检测与图像识别分类的区别?

目标检测与图像识别分类的区别 目标检测和图像识别分类是计算机视觉领域中两个重要的任务&#xff0c;它们在处理图像数据时有一些区别。 目标检测是指在图像中定位和识别多个目标的过程。其主要目标是确定图像中每个目标的边界框位置以及对应的类别标签。目标检测任务通常涉…

AS/400-对象管理-01

对象管理 对象对象构图 AS/400中的库命令Display Library List (DSPLIBL)Create Library (CRTLIB)Display library (DSPLIB)Edit Library List (EDTLIBL) Source physical file 物理文件创建物理文件的命令 &#xff1a; CRTSRCPF 物理文件查看所有物理文件的源文件创建源文件…

计算机毕业设计选题推荐-戏曲文化苑微信小程序/安卓APP-项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

案例分析真题-Web系统

案例分析真题-Web系统 2011 年真题 【问题1】 骚戴理解&#xff1a;还是要学会分析&#xff0c;首先要先看题目在看文字内容描述&#xff0c;不然看完了也不知道看了个啥&#xff0c;根据“其中互联网上用户对公司产品信息的访问情况需要借助两种不同的第三方 Web 分析软件进行…

登录rabbitMQ管理界面时浏览器显示要求进行身份验证,与此站点连接不安全解决办法

问题描述 最近在黑马学习rabbitMQ的过程中&#xff0c;在使用docker部署好rabbitMQ后&#xff0c;使用账号为&#xff1a;itcast&#xff0c;密码为&#xff1a;123321 登录的时候浏览器显示了这个问题&#xff0c;如图所示&#xff1a; 当时以为自己需要输入自己的浏览…

14个最实用的WordPress SEO插件推荐

在这篇文章中&#xff0c;将为你推荐最有利于网站SEO的WordPress插件&#xff0c;这里介绍这些插件的主要功能及使用技巧&#xff0c;合理使用它们将有助于网站SEO排名。无论你是一个刚刚开始的博客作者&#xff0c;还是一个经验丰富的企业网站管理员&#xff0c;我们都将帮助你…

Android使用Hilt依赖注入,让人看不懂你代码

前言 之前接手的一个项目里有些代码看得云里雾里的&#xff0c;找了半天没有找到对象创建的地方&#xff0c;后来才发现原来使用了Hilt进行了依赖注入。Hilt相比Dagger虽然已经比较简洁&#xff0c;但对初学者来说还是有些门槛&#xff0c;并且网上的许多文章都是搬自官网&…

微信小程序设计之页面文件pages

一、新建一个项目 首先&#xff0c;下载微信小程序开发工具&#xff0c;具体下载方式可以参考文章《微信小程序开发者工具下载》。 然后&#xff0c;注册小程序账号&#xff0c;具体注册方法&#xff0c;可以参考文章《微信小程序个人账号申请和配置详细教程》。 在得到了测…

day05 语法基础——CG语法 23.10.29

1.ShaderLabVS Pro插件安装(仅vs全家可用) 2.CG语句写在哪里 3.基础数据类型 4.特殊数据类型 5.Swizzle操作符 6.运算符相关 7.流程控制语句 8.函数 9.顶点/片元着色器基本结构 10.语义 11.顶点/片元着色器传递更多参数 12.ShaderLab属性类型和CG变量类型的匹配关系 13.CG内置…

亚信科技发布“电信级”核心交易数据库AntDB7.0,助力政企“信”创未来!

昨日&#xff0c;亚信科技AntDB数据库 7.0产品线上发布会成功举办&#xff0c;数千位关注亚信科技、关注国产数据库&#xff0c;致力于推动数据库行业变革的专家、客户热情参与&#xff0c;并对发布会及产品给予高度评价。 新增两大技术特性 作为我国最早一批独立研发的通用型…

动静分离技术

一、HAproxy 动静分离 1、概念&#xff1a; HAproxy 动静分离技术是一种用于优化 Web 服务器性能和提高用户体验的策略&#xff0c;它通过将动态内容和静态内容分别路由到不同的后端服务器来实现&#xff0c;减轻服务器负载&#xff0c;提高网站的响应速度。 动态内容包括由…

2023年双十一如何选购最新fl studio 21多少钱?有FL Studio21中文解锁版下载

如果你一直梦想制作自己的音乐(无论是作为一名制作人还是艺术家)&#xff0c;你可能会想你出生在这个时代是你的幸运星。这个水果圈工作室和上一版之间的改进水平确实令人钦佩。这仅仅是FL Studio 21所提供的皮毛。你的音乐项目的选择真的会让你大吃一惊。你以前从未有过这样的…