DS

我太菜了所以什么东西都想写一下。废话太多见谅。

P4314 CPU 监控

超级经典题。

以下内容只是借这个题的位置写一下。

考虑我们不打 tag 的线段树是在维护什么东西,能看出只需要让这个东西有结合律就够了,这让我们能够拼接若干的子区间。
那么有区间修改的时候怎么办呢?我们能直接打 tag,当且仅当我们可以求出一个区间展开所有运算后,在两两之间插入一个 tag 运算后的结果是可以知道的。(修改的运算和询问的运算可以不是同一种。但是都要分别有结合律,分别有结合律的意思就是你感受一下,我说不明白。)

我们给一个节点打 tag 的时候,只能保证访问到它和它祖先,不然复杂度不对啊。因此我们只能保证某个时刻祖先上所有 tag 比当前节点 tag 更晚。具体就是直接 pushdown,运算接到后面就是对的。但是这要求我们能给 tag 打 tag,比较方便的方式就是用矩阵刻画,但是这第一可能更慢,第二可能完成不了某些东西。

结果就是你只需要给每个线段树节点维护一个向量,每次打上 tag 的时候做向量乘矩阵就行了。

这个题也告诉我们,区间赋值区间加的时候可以考虑颜色段均摊把区间赋值完全转为做区间加。

P5354 [Ynoi Easy Round 2017] 由乃的 OJ

按位考虑,找到路径上最后一个 or 1 或者 and 0,然后求一下后有几个 xor 1 即可,第一步考虑树剖只在乎若干个前缀和一个区间,那你询问一个前缀相当于可以摊回修改上,那修改查询就都是 log V*log n 了。

我草,没看见 log V>log n,难道我真的是弱智?

这种东西考虑怎么把 log V 换成 log n,大概是要压起来维护。

线段树维护经过每个区间的全 0/全 1会变成啥,跨段随便位运算。然后就随便 \(q \log^2 n\)

这启示我们可以通过换维后位运算的手法把 \(\log V\) 变成 \(\log n\)。诡异操作那个题同理。

bonus: 单 log

UOJ 671. 【UNR #5】诡异操作

如果我们两个操作都暴力,复杂度随便搞一下大概是 \(O(n \log^2V+q\log n)\) 的(可能前面还要多一个 \(\log n\) 但是我没分析明白)。分析方式类比只有除法的情况,就是如果当前节点被修改区间完全包含,那就消耗势能,因为线段树有 \(O(n)\) 个节点,让每个节点的势能是 \(\log\max a_i\)\(q\) 上只有定位区间的复杂度。

那我们考虑让其中一个修改打 tag。区间与区间 \(\max\) 当然不好做,但是 \(\operatorname{or}\)\(\max\) 最多只差不到两倍。在我们比较关心的 \(\max=1\) 的时候表现也是对的,把这个当做判断依据即可。哦或者可以考虑成,势能是 \(\operatorname{or}\) 的最高位位置?

但是我们怎么维护和呢,一个 trick 是每个节点上维护某个位为 \(1\) 的数有多少个。这时候很不幸我们 pushup,pushdown,updtag 也都要变成 \(O(\log V)\) 了,所以总复杂度是 \(O(n\log^2 V+q\log n\log V)\) 了。

看起来很没救啊。纵览这个算法。发现这个算法在叶子上的桶很稀疏而且瓶颈几乎在这,所以转置。每个节点上维护 \(\log len\)\(O(V)\) 的数,表示有哪些 bit 的出现次数在这一位是 \(1\)。这时候我们修改叶子是 \(O(1)\) 的了。pushdown 的时候,我们要清除所有数的某些位置;pushup 的时候,我们需要模拟加法进位,随便从低到高做维护进位;打 tag 和 pushdown 同理。这样我们信息传递做到了 \(O(\log len)\)

这样回看我们整个算法,定位区间的复杂度由于 pushup/down 变成了 \(O(q\log^2 n)\);这个时候我们每个节点被完全覆盖时的访问还是 \(\log V\) 次,总复杂度算上 pushup/down 是 \(\log V\sum_{i=0}^{\log n}i\ 2^{\log n-i}\)\(O(n\log V)\)。两部分加起来可以通过。

P5311 [Ynoi2011] 成都七中

记得去做。

P6580 [Ynoi2019] 美好的每一天~ 不连续的存在

原题面:

给定贡献数组 \(w\)\(n\) 个点的数,每个点有一个 \(c\) 以内的颜色;\(m\) 次查询,问保留 \([l,r]\) 的节点后,所有连通块中【出现了奇数次的颜色的个数】对应位置的 \(w\) 的和。
\(n,m\le 10^5\)\(w_i,c\le 10^4\)

连通块信息通常不好维护,直接考虑回滚莫队。

如果我们甚至不考虑撤销,那给每个连通块维护一棵每一位是 0/1 的线段树,外层并查集合并的时候线段树合并 xor 一下每个位即可。但是怎么撤销呢?

发现,我们可以控制回滚莫队只增加一个端点,而 \([l,r-1]\) 合并上 \(r\) 的代价一定不超过 \([1,r-1]\) 合并上 \(r\) 的代价,而我们一个一个合并总代价是 \(n \log c\) 的,按照每一步合并的代价给每个位置赋权分块,复杂度 \(O(n\log c\sqrt{m})\)

新版题面只需要随便维护启发式合并即可。

这启示我们莫队几乎只需要在乎总代价。

bonus: 单 sqrt

P5355 [Ynoi Easy Round 2017] 由乃的玉米田

考虑前两个操作,看着就几乎不能维护,上 bitset。莫队的时候维护当前区间桶的正反 bitset,\(+-\) 询问是简单操作。考虑 \(\times\),枚举两个因数中较小的一侧即可。考虑 \(\div\),如果 \(x>\sqrt V\),枚举商;如果 \(x\le \sqrt V\),对于每种 \(x\) 分别随便做一下即可,具体就是扫描线维护上一个可以和当前位置匹配的东西之类的。

\(O(q(\frac{V}{\omega}+\sqrt V)+n\sqrt q)\)

根号分治典题。

posted @ 2026-08-02 02:56  zcz0263  阅读(13)  评论(0)    收藏  举报