2025年2月杂题集
2025年2月杂题集
目录
- P5904 [POI 2014] HOT-Hotels 加强版
- P10085 [GDKOI2024 提高组] 染色
- P1935 [国家集训队] 圈地计划
- [ARC107F] Sum of Abs
- P9878 [EC Final 2021] Check Pattern is Bad
- CF888G Xor-MST
- P4098 [HEOI2013] ALO
- P4585 [FJOI2015] 火星商店问题
- [AGC023F] 01 on Tree
- P9678 [ICPC 2022 Jinan R] Tree Distance
- P4757 [CERC2014] Parades
- P5065 [Ynoi2014] 不归之人与望眼欲穿的人们
- ARC192C - Range Sums 2
- P5279 [ZJOI2019] 麻将
- P4336 [SHOI2016] 黑暗前的幻想乡
- P3317 [SDOI2014] 重建
- P4455 [CQOI2018] 社交网络
- P6097 【模板】子集卷积
- AT_arc100_c [ARC100E] Or Plus Max
- AT_abc212_h [ABC212H] Nim Counting
- jzoj 7366 可怜的木偶 (dance)
- SP11470 TTM - To the moon
- AtCoder WTF2019 A
- AT_awtf2024_d Almost Bubble Sort
- P7771 【模板】欧拉路径
- P6628 [省选联考 2020 B 卷] 丁香之路
- AT_agc018_f [AGC018F] Two Trees
- ARC193B Broken Wheel
- P8528 [Ynoi2003] 铃原露露
- P9166 [省选联考 2023] 火车站
- P2391 白雪皑皑
Part 1
P5904 [POI 2014] HOT-Hotels 加强版
长链剖分与 DP 练习题。首先推出
对于长链上的儿子直接用指针继承状态,注意要精细实现才能不发生内存混乱。而对于非长链上的儿子则暴力合并。有点类似启发式合并的感觉。
有一些转移式子是枚举两个儿子,需要开一个临时数组记录前缀和优化复杂度。
P10085 [GDKOI2024 提高组] 染色
染一次是这样:
.o. ooo .o.
如果再把周围四个方向都染上就会变成:
..o.. ..... o.o.o ..... ..o..
我们把它称作
以此类推,每
注意到如果我们放一个
于是我们依次缩小十字架的长度,最后就能知道哪些点染的是
P1935 [国家集训队] 圈地计划
类比文理分科。变成最小割模型,割完后与
注意到这道题是相邻不同有额外贡献,而不是相同,那么我们可以先黑白染色,黑点是左
此时额外贡献就很好表示了,还是从
最后答案就是总和减去最小割。
[ARC107F] Sum of Abs
还是最小割模型,不过建模需要仔细斟酌。
最理想情况下,答案应该是
- 删掉这个点,使答案减少
。 - 一个
的点放入取正的连通块,使答案减少 。 - 一个
的点放入取负的连通块,使答案减少 。
所以把一个点拆成两个点
我们还有一个连通块内正负性相同的限制,所以如果
P9878 [EC Final 2021] Check Pattern is Bad
构造题。
Part 1 判断原图是否已经不合法。
Part 2 首先把能确定的都确定了,即把形如
WB B?
这样的可以直接将问号换成 B
。
我们正反扫两次就能把这些填完。过程中如果出现填两个颜色都不合法的格子也要输出 NO
。
Part 3 每次对于剩下的问号,随机填,每填一个就从它开始搜索把能确定的都确定了。注意可能不合法需要回溯,因此要记录搜索时填了哪些位置。
Part 2
CF888G Xor-MST
看到异或首先想到 01-Trie。考虑 Kruscal 的过程,每次找到一条最小的边,看是否能连上。
发现在 01-Trie 上,两点的异或和主要与它们的 LCA 深度有关。
因此我们可以联想到,
现在我们只要对每一个分叉,求出在左右子树中各选一个点,求最小的异或和,可以枚举 Size 较小的一个子树,然后在另一个子树内查询。根据启发式合并的思想,这样枚举是均摊
我们可以事先对
P4098 [HEOI2013] ALO
枚举一个
可以用 ST 表加二分求出前驱最大值和后继最大值,然后我们需要区间查询异或和的最大值,用可持久化 Trie 即可。
时间复杂度
P4585 [FJOI2015] 火星商店问题
写起来感觉有一点 shi 的数据结构题。
首先有一个线段树套可持久化 Trie 的做法,对商店开线段树,对时间可持久化,这样时间和空间都是
有一个使用线段树分治可以做到时间
我们把询问的时间区间插到线段树上,于是一件物品就是单点插入,可以用 vector
按商店编号排序,自顶向下更新询问。
01-Trie 则显然就是按商店编号可持久化了。这样做每到一个节点会开一个 Trie,而用完就删掉了,因此空间可以少一个
[AGC023F] 01 on Tree
被称作 Exchange Argument(临项交换)技巧的贪心题。
这道题和之前 abc 的某道 G 题很像。
考虑自顶向下删点很难做,我们可以从独立的
而我们需要确定一个连边的顺序,这里用了 Exchange Argument 的 Trick。如果连通块
于是将
每次取出优先队列的 top
,然后将其合并到它父亲的连通块,使用并查集维护连通块。
由于还要计算答案,需要在每个连通块维护一个
P9678 [ICPC 2022 Jinan R] Tree Distance
双倍经验:P9058 [Ynoi2004] rpmtdq。
以下
我们把
瓶颈在于点对有
如果点对
和 满足 则 显然是没有用的,我们称 被 支配。
如果点对不被任何另一对点支配,则 称作支配点对。
我们可以找到一种支配点对的必要条件。将所有可能为支配点对的点对加入集合
由于是与点对有关的信息,考虑点分治,设当前分治重心为
先给出结论:对于
所以
因此只要对
可以将连通块内的点排序后使用单调栈维护。
这样连通块内的每个点都有
剩下的就很简单了,离线后对
时间复杂度
Part 3
P4757 [CERC2014] Parades
模拟赛场切的一道题。
由于贪心不可做,所以考虑 DP,首先想设
那么考虑把路径挂在 LCA 上选,对于当前点
除此之外选路径
我们可以先用这些路径初始化
最后的问题如何算路径的贡献,有了状态压缩的
可以使用树状数组运用差分做子树加、单点查。
时间复杂度
P5065 [Ynoi2014] 不归之人与望眼欲穿的人们
模拟赛没做出来的一道分块好题。
首先有一个性质:固定区间左端点后,不同的右端点最多有
那么据此可以写出一个
我们现在要处理出一个数组
由于只有
可以用链表实现,当插入左端点
每次修改都这样暴力重构。
考虑改进这个做法,瓶颈在于修改时所有位置都扫了一遍太浪费了。考虑分块,设块长为
那么合法的区间分为在一个块中和跨越多个块的情况。
在一个块中
修改时用上面的做法暴力重构一个块,查询时枚举每个块接着做二分,复杂度
跨越多个块
还是运用上面的性质,一个块内的前缀或后缀只有
记
那么我们可以枚举块
后者可以每次暴力重构时处理出一个
前者可以在从小往大枚举
而处理
取
ARC192C - Range Sums 2
简单交互题,由于
如果
当
P5279 [ZJOI2019] 麻将
DP 套 DP 练习题,用时 2h10min。
首先我们先建一个能不能判定当前局面是否能胡的自动机,然后在自动机上 DP 即可。在此之前可以先写出判定的 DP 式子然后建自动机。
首先我们只需考虑每种牌的个数。我们先来判定五个面子的情况,设
注意到到
于是自动机上的每个点需要记录两个
另外对于七个对子的情况,只需再在自动机上的每个点记录当前遇到的对子数
那么一个节点胡了当且仅当存在一个
实现可以使用 map
里面套两个 vector
和一个 int
。注意初始化时只有
转移时枚举新增
新增 张牌,转移到 。 新增 张牌,转移到 。 新增 张牌,转移到 。 - 当
时 。
转移时再枚举与
注意
发现算上初始点和胡节点只有
我们不要枚举排列,而枚举每种牌选的个数,通过阶乘算出排列的贡献,具体来说设
那么设初始有
最后设
可以理解为前者是第一张牌,后者是选了
时间复杂度为
P4336 [SHOI2016] 黑暗前的幻想乡
容斥+矩阵树定理。
矩阵树定理(无向图)
矩阵树定理用于求一张图的生成树个数(生成树点数等于原图点数)。
定义邻接矩阵
则生成树个数为
行列式求值
定义如下,其中
直接计算是
以下
- 交换
行列式取反。 , 为常数,行列式不变。 , 为常数,行列式不变。
那么我们可以将原矩阵高斯消元成仅
本题
由于同一种颜色的边不能重复选,所以可以考虑容斥,
时间复杂度
Part 4
P3317 [SDOI2014] 重建
如果直接套上矩阵树定理,这里度数矩阵即所有边权的和,发现 WA 了,为什么呢?我们考虑一下答案的构成:
答案应该是枚举所有树
而矩阵树定理根据定义应该是所有可能树的边权乘积的和,即
那么后面那一坨东西怎么办呢?发现后面可以化成这样:
代入得
由于我们用了除法,当
时间复杂度
P4455 [CQOI2018] 社交网络
矩阵树定理(有向图)。
邻接矩阵
对于外向树(边从根连向叶子方向的树),以
对于内向树(边从叶子连向根方向的树),以
本题
直接套用矩阵树定理即可,本题是以
P6097 【模板】子集卷积
题意是计算
前面
即设
那么我们可以计算
其中
那么最后答案即
在计算
但是 FWT 有一个性质,变换后的数组是可加的,即
所以计算出所有
AT_arc100_c [ARC100E] Or Plus Max
SOS DP。
题意:对于每一个
我们可以转而计算对于每个
时间复杂度
AT_abc212_h [ABC212H] Nim Counting
FWT 的可加性、等比数列求和。
算法 1 做
算法 2 由于 FWT 的可加性,我们可以只做一次 FWT 卷积,我们现在就是要对每一项求
使用矩阵快速幂写出以下式子可以做到
事实上
设
为首项, 为公比, 为项数,其中 。
当
时。 当
时。
时间复杂度
Part 5
jzoj 7366 可怜的木偶 (dance)
由于
给出结论,如果确定了
- 证明答案不小于
:因为所有数都是 的倍数,且初始时 也是 的倍数,所以不能走到不为 倍数的位置,则不能小于 。 - 证明可以达到
:考虑前 个数的 为 ,现在加入第 个数 ,根据裴蜀定理 一定有整数解,即可以通过走若干次 和 走到 ,因此 个数可以走到 。
考虑设
根据莫比乌斯反演,
最后的答案即为
根据实现可以做到
更优的复杂度
展开得
枚举
枚举
根据狄利克雷卷积
套上数论分块可以做到
SP11470 TTM - To the moon
区间加的可持久化线段树。
调了很久终于发现了问题所在:由于用了标记永久化,标记不下传,因此不能从两个子树合并贡献,需要在修改下传时在每个节点加上贡献。
void update(int &x,int y,int l,int r,int L,int R,int z){ if(!x) x=++tot,ls[x]=ls[y],rs[x]=rs[y],tag[x]=tag[y],s[x]=s[y]; s[x]+=(ll)(min(R,r)-max(L,l)+1)*z; if(L<=l&&r<=R) { tag[x]+=z; return; } if(L<=mid) { if(ls[x]==ls[y]) ls[x]=0; update(ls[x],ls[y],l,mid,L,R,z); } if(R>mid) { if(rs[x]==rs[y]) rs[x]=0; update(rs[x],rs[y],mid+1,r,L,R,z); } }
其中第三行 s[x]+=(ll)(min(R,r)-max(L,l)+1)*z;
很重要,并且最后不应该 s[x]=s[ls[x]]+s[rs[x]]
。
AtCoder WTF2019 A
考虑到每次把
我们应该要做
考虑到
也就是对于除了第一轮的每一轮,我们可以选择一个盒子不用开,因为这个盒子在上一轮的最后开过了。
那么令
每次开一个盒子时让
当存在
AT_awtf2024_d Almost Bubble Sort
相当于选一个下标集合
发现它又等于
如果考虑把
由于最后有一个关于
我们可以初始让所有点都不选
P7771 【模板】欧拉路径
欧拉路径:一个图中经过每条边恰好一次的路径,允许经过重复点。
欧拉回路:起点与终点相同的欧拉路径。
对于连通图,欧拉路径有如下判定:
- 对于无向图,恰好有两个点度数为奇数时,存在起点与终点不同的欧拉路径,且起点与终点就是这两个奇度数的点。
- 对于无向图,所有点度数均为偶数时,存在欧拉回路。
- 对于有向图,存在一个点
满足 ,且存在一个点 满足 ,且其他点入度等于出度,则存在起点与终点不同的欧拉路径,且 是起点, 是终点。 - 对于有向图,所有点入度等于出度,存在欧拉回路。
寻找欧拉路径
基本思想:定义递归函数
算法实际上不太一样,对于
- 首先遍历每条未走过的出边(可能之前调用过
导致一些出边已走过)到 。 - 调用
。 - 当所有出边都遍历完后,将
加入答案序列。
最后倒序输出答案序列即题目所需的答案。
本题还要求字典序最小,因此需要将出边排序,用 vector
记录出边。
实现上对于每一个点
Part 6
P6628 [省选联考 2020 B 卷] 丁香之路
考虑题目要求的路径就是从
那么接下来就是要用最少的边权使原图变为合法的欧拉回路。
我们从
但图还有可能不连通,考虑把有边的点对用并查集缩点,相邻的点之间建边,然后跑最小生成树,发现欧拉回路的答案就会加上两倍最小生成树的权值。
时间复杂度
AT_agc018_f [AGC018F] Two Trees
很厉害的结论题。
由于
否则我们可以这样构造:
先将两棵树的根连向一个超级根,那么现在所有节点都等价了。
对于度数为奇数的点,我们将它们在两棵树上的点连起来。
那么现在所有点都是偶数度数,我们跑出欧拉回路。
对于原本是偶数度数的点,
对于原本是奇数度数的点,如果额外的那一条边在回路上是从左走到右,那么
证明:对于树上一个点,欧拉路径进出其子树偶数次,其中一次经过其与其父亲的连边,剩余奇数次进出其子树内的额外边,且进入和出去的次数恰好相差
ARC193B Broken Wheel
因为
显然一种
我们根据
那么我们指定
,计算 。 ,计算 。 ,计算 。
以上,发现会算重的情况当且仅当
所以最后将答案减
P8528 [Ynoi2003] 铃原露露
考虑对于
- 若
,则对于 的区间不合法。 - 若
,则对于 的区间不合法。
可以想到一个树上启发式合并的过程,维护每个点子树内
由于不合法的区间是包含
每次合并一个节点产生
接下来的问题形如给一个矩形加,然后查询矩形内为
扫描线以后,就是区间加,差分后查询区间为
具体来说,我们维护维护区间最小值、最小值的个数、
标记需要维护加标记、历史标记。历史标记表示区间内最小值会对历史和贡献多少次。
下传历史标记时需要知道哪些子区间是原先的最小值,因此上传时需要记录区间最值由哪些子区间转移而来。
每次如果全局的最小值为
时间复杂度
P9166 [省选联考 2023] 火车站
对于一条轨道
由于轨道之间是没有区别的,所以可以差分实现区间加
查询则从
Part 7
P2391 白雪皑皑
由于后来的区间会覆盖之前的区间,我们考虑倒着做,那么每次就要覆盖区间内的
考虑并查集维护一个点后继的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通