• 关于吉利线段树


    引言

    这玩意儿又称(Segment Tree Beats) 。由吉老师、(Picks)、美国队长三位知名毒瘤发明。
    我的精神受到了污染......

    线段树简介

    线段树什么的太难了,不是很会啊.....
    线段树最强的地方在于,如果标记支持合并,那么我们就能够快速进行区间修改了。

    一类特殊标记

    维护这样一个标记((a,b)) ,表示(x o max(x + a , b))
    显然标记可合并:((a,b) + (c,d) = (a + c , max(b + c , d)))
    这个标记可以同时处理区间加法、区间覆盖,对应为((add,-inf))((-inf , cov))
    这个标记还能取(max)(max((a,b) , (c,d)) = (max(a,c) , max(b , d)))
    由于该分段函数取上平面交后段数不变,所以支持维护历史最大值,可以说是相当好用了。
    然而这个东西在解决历史最小值,区间取(min)等一系列问题上无能为力,所以我们需要另辟蹊径。

    一类历史最大、最小值问题

    设当前最大值为(mx)、最小值为(mn)、修改增量标记为(t)
    设历史最大值为(hmx),历史最小值为(hmn)
    直接维护不好维护,我们考虑维护历史最大标记(mxt)、历史最小标记(mnt)
    可以理解为,这个历史最大标记(mxt)是修改标记(t)的一个最大前缀和,历史最小标记(mnt)类似。
    那么下放就很简单了。
    先用新的前缀和更新所有历史最优值:
    (mx + mxt' o hmx)(mn + mnt' o hmn)(t + mxt' o mxt)(t + mnt' o mnt)
    然后再把当前值改为真实值:(t' o t)(t' + mx o mx)(t' + mn o mn)
    当然这些标记不一定要是加法标记。
    只要是支持合并,并且能够定义大小关系的标记,我们都可以这么做。
    例题:
    [UOJ164]【清华集训2015】V ; 代码

    一类趋近问题

    当修改操作逐渐使得元素趋近于相同时,往往就可以搞事情。
    目前已知的这类操作:

    • 区间开根 + 加法 + 求和
    • 区间或 + 与 + 求和
    • 区间除法 + 加法 + 求和

    解决方案就是:若该修改对当前区间影响相同则打标记,否则暴力递归处理。
    比如,对于开根、除法操作,记录区间最小、最大值。
    对于区间或 + 区间与操作,记录区间内每一位是否相同(用位运算即可所有位一起实现)。
    例题:
    [BZOJ5312]冒险 ; 代码
    [UOJ228] 基础数据结构练习题 ; 代码

    一类区间最值问题

    势能分析之类的略过,反正我口胡的势能分析连我自己都不知道对不对。
    以区间取(max)为例。
    维护区间最小值(mn)、区间次小值(se)
    对于区间对(x)(max)操作,首先定位到(log)个线段树结点,然后从它们开始(dfs)
    设当前点为(u)
    (x leq mn_u) ,显然该操作对区间无影响,(return)
    (mn_u < x < se_u),我们维护最小值修改标记(t),把最小值改为(x)即可。
    (se_u leq x) ,暴力递归。
    显然加法操作可以直接维护,额外维护一个标记(d)表示最小值之外的其他数的修改量。
    注意一点:(pushdown)时,若(se_u = inf) , 那么(se_u) 不能被修改,因为我们要保证势能分析时关键点的数量。
    同时(pushdown)的时候,我们要讨论儿子的每个值对应哪个标记,进行对应修改。
    区间取(min)是一样的,维护区间最大值(mx),区间次大值(se)即可。
    需要注意的一点:
    当我们需要同时支持区间(max)、区间(min)的时候,取(max)时要考虑它对最大值的影响,取(min)时要考虑它对最小值的影响。
    我们的加法标记要分为三类:(mn.t)(mx.t)(md.t),分别对应区间最大值增量、区间最小值增量,非最大最小值增量。
    一样的(pushdown)时要考虑儿子每一个值对应的修改应该是哪一个,然后用其属于的修改标记进行修改。
    例题
    [BZOJ4695] 最假女选手 ; 代码
    [BZOJ4355] Play-with-sequence ; 代码

    当所有问题混到一起?

    线段树各种操作大融合。
    没什么好说的,按照上面的方法一个一个实现即可。
    代码必须模块化,并且是条理清晰的模块化,否则这种题是调不出来的。
    例题
    [UOJ169] 元旦老人与数列 ; 代码
    [UOJ170] Picks loves segment tree VIII ; 代码

  • 相关阅读:
    [工作积累点滴整理]虚拟化、云计算配置规划<一>
    视频监控——从其他浏览器打开低版本IE方案
    好记性不如烂笔头-nginx安装环境与Linux安装ftp组件
    (阿里巴巴)数据库连接池——Druid (未完持续更新)
    条形码和二维码编码解码工具类源码
    JS防抖与节流函数封装
    根据设备width(375)动态设置font-size
    JS写一个简单日历
    js常用身份校验规则
    list之flex布局写法及禁止橡皮筋效果
  • 原文地址:https://www.cnblogs.com/GuessYCB/p/10349422.html
Copyright © 2020-2023  润新知