<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>李超线段树 on Zirnc's Blog</title><link>https://blog.chungzh.cn/blog/%E6%9D%8E%E8%B6%85%E7%BA%BF%E6%AE%B5%E6%A0%91/</link><description>Recent content in 李超线段树 on Zirnc's Blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Tue, 16 Aug 2022 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.chungzh.cn/blog/%E6%9D%8E%E8%B6%85%E7%BA%BF%E6%AE%B5%E6%A0%91/index.xml" rel="self" type="application/rss+xml"/><item><title>李超线段树笔记</title><link>https://blog.chungzh.cn/oi-history/li-chao-tree/</link><pubDate>Tue, 16 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.chungzh.cn/oi-history/li-chao-tree/</guid><description>线段树之标记永久化 普通的线段树在做区间修改时依赖懒标记（lazy tag），当我们从一个点向下访问时，需要将标记 pushdown。能否避免如此多的 pushdown 操作呢？这时需要用到标记永久化技巧。
我们要做的就是将 lazy tag 永久地留在当前的结点，这时子树中的所有结点都不会被这个 tag 所影响。因此，子树中询问的最大值 = 实际最大值 - tag。当我们想得到正确答案时，只要将子树返回的最大值加上当前 tag 即可。
标记永久化存在局限性，需要满足不同的修改操作可以交换顺序，或者说对答案的贡献是独立的这一条件。
举个例子：区间设置+区间加法，先设置后加和先加后设置的结果是不一样的，因此不能交换顺序。如果使用标记永久化，就可能改变了这个顺序。
比如我们先设置后加，并且令设置的区间比加的区间大，因此加的 tag 在下方，设置的 tag 在上方。 根据前面的方法，我们会从下往上取 tag，也就是先加法，再设置。 这时我们发现，由于上层是一个设置操作，下面的所有答案最终都变成了设置的那个数字，下层操作就失效了。显然有问题。 总结：标记永久化就是不再下放标记，而是让标记永久地停留在当前结点上。在统计答案时再考虑标记的影响。
复杂度分析：由于标记不会下放，但如果有两个标记落在了一个结点上，我们不会分别存储这两个标记，而是加起来合成一个标记（$(+2) + (+3) = (+5)$）。因此，每个结点最多只有一个标记。询问时最多考虑 $\log n$ 个标记，复杂度和普通线段树相同 $O(\log n)$。
程序实现：
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int up(int p) { tree[p].mx = max(tree[p&amp;lt;&amp;lt;1].mx, tree[p&amp;lt;&amp;lt;1|1].mx)+tree[p].tag; } int query(int p, int l, int r, int x, int y) { if (l &amp;gt;= x &amp;amp;&amp;amp; r &amp;lt;= y) return tree[p].</description></item></channel></rss>