杂题选讲
声明 & 前言
本文基本纯手打,GenAI 贡献不超过 10%。
正如标题所言,这篇文章挑选一些杂题讲解。这些题没有统一的分类,也没有固定的算法模板(除了那几道根号分治),但特征是都有一些思维难度,或是证明复杂度较难(根号分治),也就是思维题选讲了,如某个题遇到了你不会的算法或数据结构,直接跳过即可。
这篇文章也是我个人的习题总结。写这篇文章的原因,是发现以前做过的很多难题/思维题不记得做法了,问了同学,或者看代码回忆起来了,就都写在这里了,以免忘记。
这篇文章应该会动态更新,不然后面做的题又得忘了。
题目基本按照难度递增排列。
正文
[ABC342G] Retroactive Range Chmax
题意
给定序列
1 l r x修改: ;2 i撤销:撤销第次操作; 3 i查询。
思路
线段树。如果直接做的话,会发现撤销操作极难实现,且区间取
那就不要应用 tag 了。我们可以用一个 set 把所有 tag 存下来,撤销时只需按照修改的方式,递归到节点,直接删除 tag 即可。因为我们需要删除 tag,所以这里的标记不能下传,即所谓的标记永久化技巧。
P6374 「StOI-1」 树上询问
题意
给定
思路
做法很多,这里讲解重剖做法。
分别找到
树剖 LCA 写法可以使用如下代码寻找
1 | int get(int u, int v) { |
这是我做题的时候在讨论区看到的,忘了是哪一位大佬了。
P8366 [LNOI2022] 题
题意
给定长度为
, ; , ; ,是 的一个排列且逆序对数为奇数。
思路
动态规划。
显然只有排列
当
当
当
答案即为
CF2126G2 Big Wins! (hard version)
题意
给定长为
思路
中位数很麻烦,但是
现在来考虑中位数。一个经典 trick 是,把
于是我们可以考虑二分中位数。这里可以使用主席树维护。因为
时间复杂度
HDU6701 Make Rounddog Happy
题意
给定数列
定义一个好子数组需要满足:该子段
。
请计算
思路
如果我们直接枚举左端点,再计算右端点数量的话,会发现无法计算。但是我们稍稍移个项:
就会发现,当最大值确定的时候,可以直接统计合法长度的数量,或者说,长度确定的时候,可以直接统计合法的最大值数量。
但是,还有另一个条件:所有元素互不相同。这个条件就可以 ban 掉大部分你在看到上面这句话之后产生的想法。比如单调栈维护左右端点,都无法解决元素不重复这个问题。
好在天无绝人之路,我们发现,把最大值单拎出来,左右两个区间是两个互不相干的子问题。所以考虑启发式分治。
我们每次找到最大值位置,计算短区间对长区间的贡献。容易知道这样是
如何计算贡献?枚举左/右端点(左还是右分类讨论,短区间在左就是左端点,反之同理),那么另一个端点只要满足长度限制就好了。如何解决重复元素问题?我们提前预处理出,对于每个元素,其合法的左/右端点最远能到哪里。具体地,记录每个元素最后出现的位置,枚举到
P2617 Dynamic Rankings
题意
给定长度为
Q l r k查询:查询区间内的第 小; C x y修改: 。
思路
主席树本质是
树状数组的原理是
修改时,相当于是在
CF1009F Dominant Indices
题意
给定一棵树,定义数组
思路
长链剖分优化 dp。
可以先设
但是这样显然是
因为这样做每条长链都恰好被合并了一次,所以是
1 | void dfs2(int u, vector<int>::iterator dp) { |
CF1709E XOR Tree
题意
给定一棵
思路
首先,任意两点间的异或和可以表示成:
其中
题目要求上面的式子不能等于
假设我们已经找到了一组不满足条件的
如何快速找到非法路径?我们可以用 set 维护每个点的子树中所有的
P13984 数列分块入门 9
题意
给定长为
思路
分块。如果直接分块,记录每个块的信息的话,会发现在时空复杂度正确的情况下,无法合并块与块的信息。
我们考虑分开计算,具体地,答案可能为完整块内的数,也可能为不完整块内的数。对于不完整块内的数,可以直接记录出现位置,每次枚举并二分计算出现次数即可。现在问题在于,完整块内的数,该如何计算贡献?
注意到,若一个数在完整块内出现过,在非完整块内也出现过,那么直接把它当作非完整块的数处理即可,因为如果我们只考虑这些数在完整块内的出现次数,那么一定不会比暴力计算的答案更优。所以我们可以以块为单位,维护任意两个块之间的众数。查询时枚举不属于完整块的数,计算出现次数并取 max 即可。
CF848C Goodbye Souvenir
题意
给定一个长度为
1 p x修改: ;2 l r询问:区间中每个数的最后一次和第一次出现位置的差之和。
思路
CDQ 分治。
设数
则区间
而同时,答案又可表示为
修改的时候,实际上就是单点更新。我们可以把所有数的出现位置存下来,每次修改时,只需把这个数
查询时,需要统计所有
P8078 [WC2022] 秃子酋长
题意
给定一个排列
思路
回滚莫队。
你会发现这题线段树比较难实现,区间合并很难,但是又考虑到这题时限较宽(5s),可以过
若我们考虑普通莫队,可以对每个数存它的的出现位置,再开一个链表维护所有位置的有序列表,每次扩展区间的时候,就可以在链表中找到当前数的前驱后继,贡献容易算出。这样是
但是我们注意到,因为我们对每个数分别存了出现位置,所以,在不考虑 set 的情况下,我们的删除操作可以做到
本题卡常。
[ABC405G] Range Shuffle Query
题意
给定长为
思路
首先,答案可以表示为
于是,问题转化为求区间内小于等于给定值的出现个数。
但是,如果直接莫队+树状数组动态维护的话,时间复杂度是
注意到,时间复杂度的瓶颈在于,每次扩展/收缩区间都需要
能够想到值域分块。修改时只需修改当前点和块内的总和/积,查询时枚举完整块的和/积再并上非完整块部分的即可。
此时,我们修改的时间复杂度来到了
[ABC259Ex] Yet Another Path Counting
题意
给定
思路
显然,对于任意两个点
我们还有一个做法:确定一个起点,然后
但是,如果我们直接枚举颜色,对所有的颜色都用同一种方法暴力求的话,是
考虑根号分治。对于点集大小
对于点集大小
设点集大小大于
综上,总时间复杂度为
所以,将
P1989 【模板】无向图三元环计数
题意
给定一张有
思路
先说结论。我们可以按照如下方式给这张图定向:
对于一条边
若
,则定方向为 ;若
,则方向为编号小的结点到编号大的结点。
下面给出证明。
我们先证引理:在定向后的有向无环图中,任意节点
假设节点
根据定向规则,对于
因为节点
显然原无向图中所有节点的度数之和为
即:
因此,任意节点的出度满足
根据引理,在定向后的图上,我们可以枚举点
- 标题: 杂题选讲
- 作者: DerRichter
- 创建于 : 2026-08-14 09:17:16
- 更新于 : 2026-08-15 07:16:04
- 链接: https://derrichter.onrender.com/2026/08/14/杂题选讲/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。