也许这里有一张图,等等就能加载出来了。
记录一些典题与妙妙(喵喵) 题。
将会收录特色淮中周赛题!大多数是淮中作业题。
题目下一行是题目的标签。
树状数组原理+应用(待填坑)
考虑以第 $i$ 个数为结尾的满足条件的区间个数。显然这段区间里 $a_i$ 只能出现一次,其一定满足是从前往后枚举时这个数的最后面的位置,或从后往前枚举时这个数最前面的位置。
尝试树状数组维护。由于正常的树状数组维护的是一段前缀,故考虑从后往前枚举。
查询时查询这个数上一个出现的位置以前的 满足要求的位置的个数,修改时在树状数组上减去上一个位置,加上这一个位置。
手搓样例可以发现最后一个数唯一可以确定,所以考虑从后往前填。具体地使用一个值域树状数组维护前缀和,考虑到第 $i$ 个数,每次二分到一个最大的树状数组内下标 $q$ 使其前缀和等于 $sum_i$,那么位置 $i$ 上的数就是 $q + 1$,最后在树状数组 $q + 1$ 处减去 $q + 1$ 即可。
P8955 P4269 P4198 P8904
我不会同时维护 $i,j,k$!那咋办?分开来维护呗!
这类线段树题的核心,首先是考虑合并两个区间信息的操作。大区间的答案可以有三种方法得到:
所以,对于线段树上的每个节点,我们只需要维护 5 个信息:区间 $a$ 最大值,$b$ 最小值,$a_i-b_j(i<j)$ 最大值,$-b_j+a_k(j<k)$ 最大值,区间答案。
区间 $a_i-b_j(i<j)$ 最大值、$-b_j+a_k(j<k)$ 最大值合并考虑方式同理。
其次,对于这类线段树题,我们还要着重考虑修改操作。但这题修改操作平凡,直接改就行。较为繁琐的修改见下一题。
本题有 $3$ 种做法,这个部分仅介绍线段树做法,另外的做法分别在 set 和珂朵莉树部分。
手搓题意可知题目中求不同前缀 min 个数,一个重要的性质是前缀 min 不增,所以一定是一段一段变小的形式,于是我们用线段树维护前缀 min,即 $b_i$。
继续考虑如何合并两个区间信息。我们发现如果左区间最右一段和右区间最左一段存的数相同,则总段数是两个区间段数和减一,否则就是两个区间段数和。
难点来了:考虑如何修改。打开草稿本,画 $b_i$ 的图理解一下!我们发现如果修改后的 $a_k$ 小于原来的 $b_k$,则意味着下面一段的 $b$ 都要变小。具体地,我们在线段树上二分到最前面的 $q$,使 $b_q \leq$ 修改过后的 $b_k$,然后 $k \sim q-1$ 的 $b$ 都要修改为改过的 $b_k$。
P7706 「Wdsr-2.7」文文的摄影布置 树上带修加强版。
两维:时间线,下标
时间线:满足可减性/或/没有下界或上界限制
二维数点理解:可减或有一个方向没有限制
拓展:维护树上路径(差分)
抱抱卧真堂。
容易发现,对于一个区间,一次操作之后,一定有 $x$ 本身或者是区间最小值被带走。那么 $m$ 次操作后,留下的一定是 $x_1 \sim x_m$ 和 $a_l \sim a_r$ 中的前 $r - l + 1$ 大数。
考虑差分,用可持久化线段树维护区间和与修改的 $x$,每次询问就是 $[1, r]$ 的答案减去 $[1, l - 1]$ 的答案。查询时在两棵树上同时二分即可。
咕咕咕。
01Trie,顾名思义,就是边权只有 $0$ 和 $1$ 两种的 Trie 树,因为它很好地满足了一般处理异或问题的“拆位思想”,所以一般被用于异或有关的问题。
一般来说,01Trie 有两种构造方式:从低位到高位插入与从高位到低位插入。从低位到高位插入,使得它能够很快地处理修改操作,一般用于带修的题目;从高位到低位插入,使得它具有一些良好的性质,例如满足贪心的最优策略等等,一般用于处理各种形式的异或最值。
在代码实现上,既有一目了然的数组实现,也有短小精悍的指针实现,大家可以都学习一下。
下面,我将列出一些 01Trie 的典型例题,探讨 01Trie 的具体应用。
考虑将所有数从高位到低位插入到 01Trie 中,每次枚举一个数,找到它在 Trie 上与它异或和最大的答案,与总答案取最大值即可。
具体地,我们枚举这个数的每一位,同时尽可能找不一样的数位往低位走。容易证明,这样一定是最大的。时间复杂度 $O(n \log V)$,其中 $V$ 是值域。
考虑维护每个点到根的路径的异或和 $a_i$。可以证明,两点 $u,v$ 间异或路径的长度为 $a_u \oplus a_v$。这样,我们就把它转换成了上个问题。这里不再给出实现。
01Trie 维护带修异或信息实例。咕咕咕。
先考虑暴力解法。dfs,每个点记录 Trie 状态,跑上面 P10471 的查询,传下去,然后回溯。这样时间复杂度是 $O(n^2 \log V)$ 的,无法接受。
观察到最后,有很多点的答案都是一样的,我们可以考虑先求出任意一对权值异或和最大的点 $u, v$,进行讨论。如果它不在 $u$ 或 $v$ 到根
P8511 加强版。
咕咕咕。
首先分析题意:用每个物品按 $q$ 从大到小来找买的人,如果这人 $b \ge c$ 答案加一。
我们有一个基于暴力的势能分析 2log 做法和一个基于 dp 的 1log 可持久化平衡树做法。
宝宝,我不会可持久化平衡树怎么办,2log 能卡过去吗?
可以的!首先给每个物品按 $q$ 从大到小排序,以每个人为节点建一棵平衡树。那么我们枚举物品 $i$,我们发现这时人有 $3$ 种,$j$ 表示第 $j$ 个人:
所以呢?所以我们把平衡树按上面的分类分成三棵,之后第二种人暴力修改插入第一种人的树,第三种人直接打 lazytag 就行。
注意到暴力改过的数最后都会变成自己的一半以下,所以每个数最多被改 log 次,所以复杂度是 $O(n \log n \log V)$。
这题啊,naive!
强制在线所以不能莫队呜呜呜。
记 $i$ 后面最近的一个 $w - a_i$ 位置为 $\text{nxt}_i$,使用线段树维护。那么查询就变成了:在 $l$ 及之后,有没有 $\text{nxt}_i \leq r$ 的。
因为 $w$ 是确定的,值域又只有 $5 \times 10^5$,我们可以把值为 $v$ 和 $w - v$ 的位置放进一个 set 里维护。
观察下图我们可以发现,在同一个 set 中,相邻的数产生的 $\text{nxt}$ 才是有意义的!如果两个相邻的数的值 $a_i, a_j$ 相等,那么 $\text{nxt}_i = \text{nxt}_j$,所以前面的那个数就是废物,不管怎样都会对统计产生重复的贡献!具体地,如果我们想让它产生贡献,那么 $l \leq i, \text{nxt}_i \leq r$,显然满足 $l \leq j, \text{nxt}_j \leq r$,还不如让 $j$ 来。
然后我们发现,对于每次修改,最多只有 $3$ 个地方的 $\text{nxt}$ 值会被修改:
然后就结束辣!
省选前调了 inf 天,也是无敌了!
咕咕咕