【学习笔记】Segment Tree Beats/吉司机线段树

news/2024/11/16 14:33:35/文章来源:https://www.cnblogs.com/LKJZYD20/p/18549071

链接

区间最值操作

HDU-5306

支持对区间取 \(\min\),维护区间 \(\max\),查询区间和。

很容易想到一个暴力,我们每一次找出这个区间的最大值 \(mx\),如果 \(mx>x\),那么暴力修改这个位置的值,否则已经修改完毕,退出,时间复杂度为 \(O(n^2 \log n)\)

打一打补丁,对线段树上的每一个区间维护区间最大值 \(mx\),这个区间中最大值出现的次数 \(t\),区间次大值 \(se\),当然还要维护区间和 \(sum\)

现在考虑打上区间取 \(\min\) 标记

  • 如果 \(mx\le x\),那么对 \(sum\) 就没有修改。
  • 如果 \(se<x<mx\),那么 \(sum=sum-(mx-x)\times t\)
  • 如果 \(x\le se<mx\),此时无法直接更新节点信息,故向下左右子树递归。我们分别 DFS 这个节点的两个孩子,如果当前 DFS 的过程中遇到了前两种情况,就直接修改打上标记然后退出,否则就继续 DFS。
点击查看代码
#include<bits/stdc++.h>
using namespace std;#define ls p<<1
#define rs p<<1|1
#define ll long long
inline char gc()
{static char buf[1 << 20/*这里很玄学,改成其他数字可能更快*/], *p1 = buf, *p2 = buf;return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20/*改成和上面一样的数字*/, stdin), p1 == p2) ? EOF : *p1 ++;
}inline void read(int &n) // 用法 read(n);
{bool w = 0;char c = gc();for(; c < 48 || c > 57; c = gc())w = c == 45;for(n = 0; c >= 48 && c <= 57; c = gc())n = n * 10 + c - 48;n = w ? -n : n;
}
const int N=1e6+7;int T,n,m,a[N],mx[N<<2],se[N<<2],cnt[N<<2],tag[N<<2];
ll sum[N<<2];inline void pushup(int p){sum[p]=sum[ls]+sum[rs];if(mx[ls]==mx[rs]){mx[p]=mx[ls],se[p]=max(se[ls],se[rs]);cnt[p]=cnt[ls]+cnt[rs];}else if(mx[ls]>mx[rs]){mx[p]=mx[ls],se[p]=max(se[ls],mx[rs]);cnt[p]=cnt[ls];}else{mx[p]=mx[rs],se[p]=max(se[rs],mx[ls]);cnt[p]=cnt[rs];}return;
}inline void build(int p,int l,int r){tag[p]=-1;if(l==r){sum[p]=mx[p]=a[l];cnt[p]=1,se[p]=-1;return;}int mid=(l+r)>>1;build(ls,l,mid),build(rs,mid+1,r);pushup(p);return;
}inline void pushtag(int p,int tg){if(mx[p]<=tg)return;sum[p]+=(ll)(tg-mx[p])*cnt[p];mx[p]=tag[p]=tg;return;
}inline void pushdown(int p){if(tag[p]==-1)return;pushtag(ls,tag[p]),pushtag(rs,tag[p]);tag[p]=-1;return;
}inline void update(int p,int l,int r,int s,int t,int val){if(mx[p]<=val)return;if(s<=l&&r<=t&&se[p]<val){pushtag(p,val);return;}int mid=(l+r)>>1;pushdown(p);if(s<=mid)update(ls,l,mid,s,t,val);if(t>mid)update(rs,mid+1,r,s,t,val);pushup(p);return;
}inline int querymax(int p,int l,int r,int s,int t){if(s<=l&&r<=t)return mx[p];int mid=(l+r)>>1,res=-1;pushdown(p);if(s<=mid)res=max(res,querymax(ls,l,mid,s,t));if(t>mid)res=max(res,querymax(rs,mid+1,r,s,t));return res;
}inline ll querysum(int p,int l,int r,int s,int t){if(s<=l&&r<=t)return sum[p];int mid=(l+r)>>1;ll res=0;pushdown(p);if(s<=mid)res+=querysum(ls,l,mid,s,t);if(t>mid)res+=querysum(rs,mid+1,r,s,t);return res;
}inline void solve(){read(n); read(m);for(int i=1;i<=n;i++)read(a[i]);build(1,1,n);for(int i=1;i<=m;i++){int op,l,r,val;read(op); read(l); read(r);if(!op){read(val);update(1,1,n,l,r,val);}else if(op==1)printf("%d\n",querymax(1,1,n,l,r));else printf("%lld\n",querysum(1,1,n,l,r));}return;
}int main(){scanf("%d",&T);while(T--)solve();return 0;
}

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

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

相关文章

【跟着阿舜学音乐-笔记】1.12和弦功能与进行原理

七和弦 七和弦是三和弦的基础上叠加三音构成的和弦(四个音的和弦)。其中小大七和弦(CmM7)很少运用,因为调内没有小大七和弦,同时听感上也不是很好。 注:有另一种和弦命名方式,即三和弦与根音呈大小七度的音组成和弦的命名法,该命名法对比上述命名法有个特例——增大七…

看过这个,你可能更了解指针一点(2)

先来看下图你认为以下的打印的结果是什么? 接下来,我们先来分析 ****在1中arr单独放在sizeof内表示整个数组, 因此计算的为整个数组大小。即6乘1得到6 1的答案为6 ****在2中arr没有被单独放在sizeof中, arr此时表示数组首元素的地址,+0则表示计算的是第一个元素地址的大小,…

stoi函数介绍

stoi 是 C++ 标准库中的一个函数,定义在头文件 <string> 中,它用于将字符串转换为整数类型。 函数原型 int stoi(const std::string& str, size_t* idx = 0, int base = 10);str(必选):要转换的字符串,必须以数字开头(可以包含正负号)。 插一句题外话 如果不…

数据采集与融合技术-第四次实践作业

gitee链接:作业4 作业①: 要求: 熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容。 使用Selenium框架+ MySQL数据库存储技术路线爬取“沪深A股”、“上证A股”、“深证A股”3个板块的股票数据信息。 候选网站:东方财富网:http://quote.eastmoney.co…

团队作业4——项目冲刺-第六篇

团队作业4——项目冲刺-第六篇这个作业属于哪个课程 <计科22级34班>这个作业要求在哪里 <作业要求>这个作业的目标 修改完善需求规格说明书、系统设计、Alpha任务分配计划、测试计划GitHub 链接 https://github.com/tangliweiwww/ChatGpt🍟一、团队 1.团队名称:…

20222306 2024-2025-1 《网络与系统攻防技术》实验五实验报告

1.实验内容 (1)从www.besti.edu.cn、baidu.com、sina.com.cn中选择一个DNS域名进行查询,获取如下信息:DNS注册人及联系方式 该域名对应IP地址 IP地址注册人及联系方式 IP地址所在国家、城市和具体地理位置 PS:使用whois、dig、nslookup、traceroute、以及各类在线和离线工…

playwright ubuntu 出现 playwright._impl._errors.TimeoutError: Locator.click: Timeout 30000ms exceeded

win系统上正常, ubuntu报错 如下报错:解决Linux环境是英文browser.new_context(locale="zh-CN")本文来自博客园,作者:__username,转载请注明原文链接:https://www.cnblogs.com/code3/p/18549315

【ARM CoreLink 系列 1 -- SoC 架构 总线 互联(interconnect) 介绍】

概述 在 摩尔定律 的推动下,集成电路工艺取得了高速发展,单位面积上的晶体管数量不断增加。片上系统(System-on-Chip,SoC)具有集成度高、功耗低、成本低等优势,已经成为大规模集成电路系统设计的主流方向,解决了通信、图像、计算、消费电子等领域的众多挑战性的难题。随…

golang: 在线上用nginx部署应用

一,启动应用: 1,编译程序 $ go build 2,用nohup启动应用的二进制程序 $ nohup /data/goapp/industry/industry >> /data/logs/gologs/back.log 2>&1 & [1] 4896 3,检查应用是否启动: $ ss -lntp | grep 3000 LISTEN 0 4096 0.0.0.0:3000 …

go fiber:路由中间件

一,目录结构:二,代码 1,中间件代码 package middlewareimport ("fmt""github.com/gofiber/fiber/v2""industry/config" )// token校验 func CheckUser(c *fiber.Ctx) error {token:=c.Query("token")fmt.Println("token:"…

20222327 2024-2025-1 《网络与系统攻防技术》实验六实验报告

一、实验内容 学习掌握了Metasploit工具的使用,具体的操作总结来说就是Search-Use-Show-Set-Exploit/run 学习了利用相关漏洞进行模拟攻击的操作,对防范恶意攻击有了一些认识(安装杀软,不要点击陌生网站、文件链接等) 二、实验过程 1、前期渗透 ①主机发现(可用Aux中的ar…

快速量产低功耗 4G 定位方案?Air201 模组来搞定!

今天我们来了解的是Air201模组快速量产低功耗 4G 定位方案,希望大家有所收获。今天我们来了解的是Air201模组快速量产低功耗 4G 定位方案,希望大家有所收获。 寻寻觅觅低功耗4G定位方案? 一个Air201就够了! ——定位准、体积小、功耗低,助力行业客户快速量产! 01 Air201是…