Segment tree beats(吉老师线段树)学习笔记

本文介绍了区间最值操作的概念,并通过吉老师线段树讲解了如何处理区间取min或max的问题。文章以HDU5306 Gorgeous Sequence和CCPC2020网络赛A题为例,详细分析了操作过程和复杂度,提供了相应的代码实现,总结了处理这类问题的关键点。
摘要由CSDN通过智能技术生成

区间最值操作

区间最值操作,指的是对区间 [ l , r ] [l,r] [l,r] 里的全部数对 x x x min ⁡ \min min 或取 max ⁡ \max max,即 a i = min ⁡ ( a i , x ) a_i=\min(a_i,x) ai=min(ai,x) a i = max ⁡ ( a i , x ) a_i=\max(a_i,x) ai=max(ai,x)

一道例题

HDU5306 Gorgeous Sequence

在这里插入图片描述
我们用线段树维护每个区间的最大值 m x mx mx 和严格次大值 s e se se,以及 m x mx mx 的个数 c n t cnt cnt
考虑 1 1 1 操作,对于一个线段树上的区间,我们分类讨论一下:

  • 如果 m x ≤ t : mx\leq t: mxt:
    那么我们可以直接 r e t u r n return return
  • 如果 m x > t , s e < t : mx>t,se < t: mx>t,se<t:
    我们在区间打一个 t a g tag tag 标记,并更新最大值为 t t t,同时更新 s u m = s u m − c n t ∗ ( m x − t ) sum = sum - cnt * (mx - t) sum=sumcnt(mxt)
  • 如果 s e ≥ t : se\ge t: set:
    因为此时我们并不知道哪些数大于 t t t,于是我们暴力递归子区间

这样子操作的复杂度看起来很玄学,但其实通过势能分析,可以推出复杂度大概是 O ( m l o g n ) O(mlogn) O(mlogn) 的,详情可参考吉老师 2016 2016 2016 年的国家集训队论文 (我实在不会啊QAQ

代码如下:

#include <bits/stdc++.h>
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
LL z = 1;
int read(){
   
	int x, f = 1;
	char ch;
	while(ch = getchar(), ch < '0' || ch > '9') if(ch == '-') f = -1;
	x = ch - '0';
	while(ch = getchar(), ch >= '0' && ch <= '9') x = x * 10 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值