『区间最值操作 & 区间历史最值』Day6

1 势能

1.1

有一类之前就见过的操作。区间取模区间开方。

开方是说在 loglogB 次过后就不变了,所以这之前暴力即可。

取模则是说如果一个数能取模那么至少会减少一半,所以一个数最多暴力操作 logB 次就没了。对于一个区间你维护最大值看是否需要递归进行操作即可。

上面的复杂度都是 O(×nlogn) 的。

1.2

区间开方,区间加,查询区间和。

为什么要按照 maxmin 的情况来?

因为我们直接用标记处理 maxmin1 的情况。剩下暴力。

而每个区间暴力最多次数还是 loglogB 的,保证了暴力复杂度。

区间加,区间除,查询区间和,查询区间 min。

还是 max - min,考虑暴力复杂度。

因为你区间加是不会让 max - min 增多的,是 log 次。

1.3

尝试对上面的情况进行总结。

你设置一个分界情况,一边暴力,一边打标记(且可以打标记);

只需要保证暴力的复杂度正确。

可以完成 T1。

查看他人代码发现没有处理区间覆盖,因为这种情况存在当且仅当之前 max=min+1,操作过后 max=min,而这种情况会暴力下去 O(len) 次,消除 O(len) 的势能。

而之前的势能一共是 O(nlogn)

2 最值

结论:维护 Max, SecondMax;每次如果 Mintag < SecondMax 就暴力向下修改,否则可以直接改 Max。

感觉分析很乱,也许我曾经证出过,记结论。

3 历史版本

3.1

维护历史标记和当前标记,下传的时候子节点一定没有被这些标记标记过。(每次 pushup、pushdown 都需要传历史最值和当前)

更新的时候就把父亲的标记 (x,y) 和儿子 (x,y) 合并即可。

说到标记,你可以把它写成多原组的形式,重定义广义下的 + 和 max。

注意,+ 不一定满足交换律;但一定满足结合律。

3.2

两种标记叠加的情况。

如果你同时有加法和覆盖标,标记都是加法,突然来了一个乘法;那么接下来你维护的标记就不能有加法了,直接把覆盖标加上即可。

4 习题

Picks hates segment tree

为什么还支持加法啊。

因为你一次减少势能使得 maxn 和 sex 消失了一个,而加法不会影响相对大小。

V

标记的广义运算。放代码上来:

struct sb {
	int x, y;
	sb () {}
	sb (int _, int __ ) { x = _, y = __; }
	sb operator + (sb t) { return sb(x + t.x, Max(y + t.x, t.y)); }
};
sb max(sb x, sb y) { return sb(Max(x.x, y.x), Max(x.y, y.y)); }

struct node {
	sb _, a;
} T[N << 2];

void upd(int p, sb _, sb t) { // 看成是,从父亲节点传下来的,历史最大值,和现在的 tag 
	T[p]._ = max(T[p]._, T[p].a + _); T[p].a = T[p].a + t;
}

序列

莫队移动。

可以按照最小值的区间线性 dp 计算,注意先考虑不规整的那一段。

posted @   LCat90  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示