zoukankan      html  css  js  c++  java
  • 「杂谈」原来我不会线段树懒标记以及永久化

    原来我不会线段树懒标记以及永久化。

    虽然很多时候用线段树只是什么区间加区间和,区间加区间最值,区间推平区间求和等等,大部分都是不知背后的所以然就瞎打标记就 ok 了,没想到背后还有道理要探寻,免得最后自己跳进了坑里才发现是线段树/树套树没写对。


    如果是正常打懒标记,是需要这个标记在时间轴上有结合律的,可以不满足交换律。

    回想线段树懒标记下放的过程就可以感性理解是为什么,因为在打标记的时候我们把标记 (t_3) 下放了,后来的标记 (t_3) 一定在前面的标记 (t_2) 后面,所以不需要满足结合律,然而下放标记 (t_2) 的时候可能和前面的标记 (t_1) 合并,但 (t_1) 还没有和更前面的标记 (t_0) 合并,如果 ((t_2 o t_1) o t_0 eq t_2 o (t_1 o t_0)) 就 GG 了,这里的 (a o b) 就是把两个标记 (a,b) 合并,前面的 (a) 合并到了 (b) 上面,是我瞎定义的符号,是为了突出这个运算是有先后顺序的。

    比方说加法乘法标记我们维护了一个 (ax+b),如果两个标记 (t_0=(a_0,b_0),t_1=(a_1,b_1)) 把他们合并,最终的标记就是 (t_1 o t_0=(a_0a_1,b_0a_1+b_1)),假设有三个先后出现的标记 (t_0,t_1,t_2),我们发现 ((t_2 o t_1) o t_0= t_2 o (t_1 to t_0))。这个就是标记在时间轴上具有结合律,但它没有交换律,(t_1 o t_0=(a_0a_1,b_0a_1+b_1),t_0 o t_1=(a_1a_0,b_1a_0+b_0)),这两个标记是不同的。


    回想起标记永久化的过程,需要标记在时间轴上具有结合律,是不是必须要求标记在时间轴上有交换律呢?

    其实是不必要的,只需要对于两个标记 (a o b),如果能找到一个 (a') 使得 (a o b=b o a'),在一个标记 (a) 在线段树上往下走的时候,如果当前节点有个标记 (b),让 (a) 变成 (a') 就可以,因为标记永久化查询的时候不会 pushdown,所以运算顺序交换了一下,但原先是 (a o b),不得不把 (a) 放在 (b) 后面合并,就把 (a) 变成 (a'),使得标记永久化查询到的 (b o a')(a o b) 是等价的。

    树套树的时候记得看一下能不能标记永久化。


    线段树题要考虑:

    • 给区间整体打标记的时候,维护的值会发生什么变化;
    • 给区间整体打标记的时候,标记之间如何合并;
    • 是否能快速地 pushup

    Reference

    zhqwq 我 根 本 不 会 线 段 树|线段树再学习笔记

  • 相关阅读:
    备忘录模式---行为型
    观察者模式(Observer)---行为型
    Hadoop基础
    centos执行-查看,复制,删除-命令的脚本
    权限问题
    12月centos单词
    配置集群遇到的问题
    SSH--完全分布式主机设置【克隆过安装过Hadoop的主机后】
    java随机排座位
    NewWord
  • 原文地址:https://www.cnblogs.com/do-while-true/p/15346589.html
Copyright © 2011-2022 走看看