09 2023 档案
摘要:这不看完就会做吗。 显然对于 SSS 每个长度为 TTT 判断即可,由于只改 333 个字符,所以我们求 LCP,然后 LCP 的下一个进行更改,最多 333 次就退出。 可以使用字符串哈希,不过我写的是后缀数组。复杂度瓶颈在于后缀排序和区间 RMQ,使用 DC3 或 SA-IS,且使用线性 RMQ
阅读全文
摘要:一个比较有趣的数位 DP。 考虑当 XXX 比较大的时候,可以暴力枚举 XXX 的所有倍数,判断是否可行,这个的复杂度是 O(BX)O(\dfrac{B}{X})O(XB) 的。这个过程类似根号分治,当 X>LX>LX>L 时暴力,我的做法中取 L=104L=10^4L=104。 对于 X≤LX
阅读全文
摘要:考虑点分治。 路径的合并,只需要求出每个点到当前重心的字符串是否可以成为模式串依次相连的前缀或后缀即可。 这显然可以哈希维护,手推一下就知道咋做了。 #include <iostream> #include <cstdio> #include <algorithm> #include <cmath>
阅读全文
摘要:*2800,不是很难,但有点卡常。 考虑 gcd\gcdgcd 不是很好直接算,经典套路是分解质因数。 对 www 分解质因数,设结果为 w=p1a1×p2a2×⋯×pkakw=p_1^{a_1} \times p_2^{a_2} \times \cdots \times p_k^{a_k}w=p
阅读全文
摘要:简单题。 考虑枚举 LCA,显然 LCA 必然是 xxx 的祖先。 由于是完全二叉树,枚举 LCA 的复杂度显然是 O(logn)O(\log n)O(logn) 的。 枚举之后,转化成子问题,求点 uuu 的子树中有多少个到 uuu 距离为 kkk 的点。 比较显然的,点 xxx 的子树中距离为
阅读全文
摘要:这不可撤销背包板子吗。 设 fif_ifi 表示凑出 iii 方案数。 加的时候加一下,删的时候减一下,注意两个循环顺序不一样,具体可以看代码理解。 #include <bits/stdc++.h> using namespace std; #define int long long const
阅读全文
摘要:一个有趣的结论是,一个图,选出若干个边集,满足他们的并为原图边集。则必有他们每个集合的 MST 的边的并,再求一次 MST 为原图的 MST。 考虑点分治,设当前重心为 uuu,设 dj=wj+dist(u,j)d_j = w_j + dist(u,j)dj=wj+dist(u,j),则有对于两
阅读全文
摘要:这为啥有 *3100。 考虑询问本质上在干什么。 树上两点之间边权最大值,相当于两点在 Kruskal 重构树(边权从小到大排序)上 LCA 的点权。 设 li,jl_{i,j}li,j 表示重构树上 iii 与 jjj 的 LCA,valival_ivali 表示重构树上 iii 的点权。 于
阅读全文
摘要:题意相当于,对 [l,r][l,r][l,r] 建出大根笛卡尔树后,求每个点的子树大小的和。 考虑点 iii 的子树大小的意义是什么?笛卡尔树上每个点的子树的编号连续。 设 LiL_iLi 表示 iii 左边第一个大于 aia_iai 的位置,RiR_iRi 表示右边第一个大于 aia_iai
阅读全文
摘要:与最小值相关,考虑求出每个点左右两边第一个小于这个数的点。可以用笛卡尔树或者单调栈维护。 设 fif_ifi 表示以 iii 为右端点的所有区间的最小值之和。考虑如何转移 fif_ifi。 设 iii 左边第一个小于 aia_iai 的位置为 preipre_iprei,则 fi=fprei
阅读全文
摘要:Kruskal 重构树板子。 考虑建边权从大到小排序后跑 Kruskal 的重构树,对于当前点 uuu 和参数 www,只能走 ≥w\geq w≥w 边,即能去的点是 uuu 祖先中最浅的点权 ≥w\geq w≥w 的点所在子树内每个叶子节点。 发现边权修改后,相对大小不变,直接在重构树点权修改即可
阅读全文
摘要:典中典。 一个点集 SSS 的 LCA 是这些点中 DFS 序最小和最大的两点的 LCA。 所以必然只会删掉最大的或最小的。 线段树或 ST 表维护一下最大和次大,最小和次小就做完了。复杂度 O(nlogn)O(n \log n)O(nlogn)。
阅读全文
摘要:感觉别人写的太复杂了。 用 set,维护当前在队列中的人。每次操作,如果有人,直接累加答案。 然后考虑怎么在 ti+sit_i+s_iti+si 时间回来。只需要离线在 ttt 里面跑一个 lower_bound 即可。 #include <bits/stdc++.h> using namesp
阅读全文
摘要:最大流 最小割,所以这是最小割树板子。 最小割树的做法是,每次在当前集合中选两个点跑最小割,然后在树上连边,权值为最小割容量。 众所周知最大流可以求出割的方案,即从源点开始,只走没流满的边,能去的点就是和源点在一起的。 把两个点集分别做上述步骤,类似分治,复杂度 O(n3m)O(n^3m)O(n3m
阅读全文
摘要:一个经典套路是,一个字符串如果重排后可以变成回文,那么其充要条件是出现次数为奇数的字符不超过 111 个。证明显然。 注意到题目的字符集是 a 到 t,这之间总共 202020 个字符。我们只关心一个字符的出现次数的奇偶性,而非具体值。也就是说,333 和 555 本质等价。不妨考虑状态压缩,每一位
阅读全文
摘要:没啥困难的。 枚举 iii,然后找出所有在 iii 后面可以出现的 kkk。对于某个 kkk,设 (i,k)(i,k)(i,k) 中有 xxx 个 aj=aia_j = a_iaj=ai,那么 kkk 的贡献是 k−1−i−xk-1-i-xk−1−i−x。 发现后面 xxx 是一个等差数列,前面
阅读全文
摘要:典中典。 考虑如果 A→BA \rightarrow BA→B 的路径中必须要经过的点与 B→CB \rightarrow CB→C 必须要经过的点,除了 BBB 点之外还有交集,那显然没有这样的 A→B→CA \rightarrow B \rightarrow CA→B→C 的简单路径。 然后显而
阅读全文
摘要:提供点分树做法。 先考虑静态问题,发现可以点分治做。具体的,对于每个分治重心,求出每个儿子子树内白点到当前重心的距离最大值。将最大和次大加起来即为两条路径拼接。 考虑动态怎么做?首先建出点分树,每个点维护两个 multiset,记为 sus_usu 和 tut_utu,分别维护 uuu 子树内每
阅读全文