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 我 根 本 不 会 线 段 树|线段树再学习笔记

  • 相关阅读:
    CF 461B Appleman and Tree
    POJ 1821 Fence
    NOIP 2012 开车旅行
    CF 494B Obsessive String
    BZOJ2337 XOR和路径
    CF 24D Broken robot
    POJ 1952 BUY LOW, BUY LOWER
    SPOJ NAPTIME Naptime
    POJ 3585
    CF 453B Little Pony and Harmony Chest
  • 原文地址:https://www.cnblogs.com/do-while-true/p/15346589.html
Copyright © 2011-2022 走看看