做题记录(2025 Aug.)
8月:
- 广东外培
- 学校上课
知识点:
- 数论分块
- hash
- FHQ
- 高维前缀和 & SOS dp
- 杂题、真题
2025.8.6
- 浅学数论分块板子,文章是这篇。
- 中间插了一道遗留的
tarjan题。
P3935
求 \(\sum_{i=l}^r f(i)\),\(f(i)\) 是 \(i\) 的因数个数。
\(1\le l < r \le1.6\times 10^{14}\)。
首先前缀和转换成求 \(\sum_{i=1}^n f(i)\)。
根据定义等转换推导:
得到数论分块基本式子,求解即可。
P2424
求 \(\sum_{i=l}^r f(i)\),\(f(i)\) 是 \(i\) 的因数和。
\(1\le l<r\le 2\times 10^9\)。
前缀和同理,把上面的式子改一改即可:
二号板子。
P2261
求 \(G(n, k) = \sum_{i = 1}^n k \bmod i\)。
\(1\le n,k\le 10^9\)。
要把式子往 \(\sum_{i=1}^n \lfloor\frac{n}{i}\rfloor\) 上靠。
需要注意最后 \(i\) 是到 \(n\) 不是 \(k\),所以要确认端点值是 \(n\) 还是 \(\lfloor\frac{k}{\lfloor\frac{k}{i}\rfloor}\rfloor\) 还是 \(n\)。同时,如果当前段的贡献已经降为 \(0\),就停止计算。
ABC414E
给定 \(N\),求满足 \(1\le a,b,c\le N\), \(a,b,c\) 互不相等且 \(a\bmod b=c\) 的 \((a,b,c)\) 组数。
\(3\le N\le 10^{12}\)。
首先 \(b\ne c\) 一定满足,看另外两对。
- 要满足 \(a\ne c\),则 \(a > b\)。
- \(a\ne b\)。
其次要满足 \(a,b,c\not = 0\),所以 \(a\nmid b\)。
那么问题就变成了求 \(a>b\) 且 \(a\nmid b\) 的二元组 \((a,b)\),\(1\le a,b\le N\)。
那么对于每个 \(b\),大于 \(b\) 的数有 \(N-b\) 个,其中 \(b\) 的倍数有 \(\lfloor \frac{N}{b}\rfloor-1\) 个,则答案就是
由于 \(b=1\) 和 \(b=N\) 的值都是 \(0\),所以可以加上。
经过拆分,得到最终公式。
P2860
给定一张连通无向图,求最少添加几条边能使图上任意两点间有至少两条没有相同边的路径。
\(N\le 5000,M\le 10000\)。
首先,在一个双连通分量里的点已经满足要求,所以我们考虑不同的连通分量之间。
缩点后图已经变成了树,树的边都是桥,问题就变成了需要几条边,使树上任意两点有两条没有相同边的路径。
这个问题的答案是叶子数除以二向上取整,具体证明见这篇。
P13357
\(T\) 组询问,每组询问给定 \(L,R\),求 \(\max_{L\le x<y\le R}\gcd(x,y)\)。
\(1\le T\le 10, 1\le L < R \le 10^{12}\)。
今天思维含量最高的一道。
首先,转化为和向下取整的除法或取模有关的问题。
先将问题变为在区间内找到两个 \(i\) 的倍数,注意到区间内最大的 \(i\) 的倍数一定是 \(R-R \bmod i\)。
那么次大的就是 \(R-R \bmod i - i\)。
所以 \(R-R \bmod i-i\ge L\),即 \(i+R \bmod i \le R-L\)。
不过不能枚举所有 \(i\),所以考虑哪些 \(i\) 不用枚举。
对于相邻的 \(i\),如果 \(\lfloor\frac{R}{i}\rfloor = \lfloor\frac{R}{i+1}\rfloor\),则有:
所以 \(i+1+R\bmod (i+1)\le i+R\bmod i\)。
那么对于 \(\lfloor\frac{R}{i}\rfloor\) 相同的数,我们只需要取最大的 \(i\),就可以通过数论分块跳了,时间复杂度 \(O(T\sqrt{R})\)。
2025.8.7
- 做 hash 题单。
- 复习数论分块和区间 DP。
P10468
给定字符串 \(S\),\(m\) 次询问,求 \(S\) 的两个子串是否相同。
\(1\le|S|,m\le10^6\)。
哈希板子。
P1481
给定 \(N\) 个字符串,求最长的字符串序列的长度,满足序列中每一个字符串都是后一个字符串的前缀。
\(1\le N\le2000, 1\le |S|\le75\)。
枚举序列的结尾,哈希看有哪些是它的前缀,都可以加入序列,对每个结果取最大值。
P6739
有一字符串 \(S\),将 \(S\) 复制后在任意位置插入一个字符得到字符串 \(T\),先给出字符串 \(T\),求 \(S\) 有无解,若有唯一解,输出 \(S\)。
\(2\le N\le 2\times 10^6+1\)。
首先 \(N\) 为偶数时肯定无解。
考虑枚举插入的字符的位置。
将去掉它后的前 \(\frac{N}{2}\) 个字符和后 \(\frac{N}{2}\) 分别计算哈希值,比较是否相等即可。
注意不同位置可能得到相同解,不能只凭满足要求的个数判断多解。
P10915
给定一字符串 \(S\),可以删除其中一个子串,求最大的 \(x\) 满足 \(\forall 1\le i\le x,S_x=S_{|S|-x+1}\)。
\(|S|\le 5\times10^5\)。
上午最难的一道。
首先把已经匹配好的给删掉,看中间,这样不会影响答案。
不难发现一定要删在左端的或者右端的,删中间的对答案没有贡献。
那么就可以枚举删掉长度和匹配的长度,看可不可行。
但是枚举两个会超时,再次观察发现答案具有单调性,所以二分匹配的长度,即可通过。
P10474
给定一 \(N\times M\) 的矩阵,\(Q\) 次询问,每次给定一个 \(a\times b\) 的矩阵,求大矩阵中是否存在子矩阵和它相同。
\(1\le N,M\le 10^3\)。
板子二维哈希,正好复习一下。
P9611
同 2025.8.6 P3935,复习一下整除分块。
P1622 & SP14846 & P13439
有 \(N\) 个犯人在连续的牢房中,其中有 \(M\) 要释放,释放一个犯人花费是左右连通(没有已经释放的空牢房)的犯人个数。
\(1\le N\le 10^3,1\le M\le 100\)。
tsy 找到的题,复习区间 DP。
不看到讨论区标题的石子合并还真难想。
考虑放犯人的反过程,将两段犯人连在一起,代价是两段犯人的数量,很像石子合并了。
注意加进来的犯人也要算贡献,考虑当前枚举到合并 \(len\) 段犯人,其中有 \(len-1\) 个犯人是加进来的,有一个是现在新加的,那么剩下的 \(len-2\) 个就要额外算上贡献。
B4336
求字符串 \(S\) 的最长回文子序列长度。
\(3\le |S|\le 10^3\)。
怀疑自己不会区间 DP 了。
没记错应该是区间 DP 典题,定义状态 \(f_{i,j}\) 表示从 \(i\) 到 \(j\) 的子串的答案。
如果 \(S_i = S_j\),\(f_{i,j}=f{i+1,j-1}\)。
否则 \(f_{i,j}=\max \{f_{i,j-1},f_{i+1,j}\}\)。
2025.8.8
- 找题做。
P3496
给定一张 \(N\) 个点 \(M\) 条边的无向图,将每个点染成黑色,白色或灰色,求能否使每个点本身和与其直接连接的点中至少有黑点白点各一个。若能,输出一种方案。
\(N\le 2\times 10^5, M\le 5\times 10^5\)。
和二分图长得就很像,考虑给图黑白染色。
需要注意,不要自己骗自己以为必须要黑白相间,走到哪里涂到哪里即可,不涂反而可能无法满足要求。
注意并非没有无解的情况,若一个连通块里只有一个点,则无解。
2025.8.10
- 找题做。
P2658
给定一个 \(N\times M\) 矩阵,在其中给出几个点,求最小的 \(x\) 使得只能往边相邻的数值差不超过 \(x\) 的格子走的情况下,所有特殊点连通。
\(1\le N,M\le500,0\le a_{i,j}\le 10^9\)。
答案显然具有单调性,二分后从任意特殊点开始 bfs 求能否连通所有特殊点即可。
MX-J19 (P13683~P13686)
A
如果总异或和为 \(0\),则所有分组情况都是二者相等,因为这两组异或后也应该是 \(0\)。如果不是,把所有分到一组即可。所以直接看总异或和。
B
考虑一位一位看,发现 \(x\) 和 \(y\) 当前位同时为 \(0\) 或同时为 \(1\) 时,可以使其异或后都为 \(1\),否则只能有一个当前位是 \(1\)。只考虑变化位的情况,因为和一定,所以考虑如何使差最小。因为最高位权值一定大于低位所有权值之和,所以把可变的最高位分给 \(x\),剩下的分给 \(y\),乘起来即可。
C
由于模数是 \(2^{64}\),只要异或出来的结果中有 \(64\) 个及以上的偶数即可,\(12\) 个偶数或 \(12\) 个奇数都可以做到,所以最多不超过 \(23\) 个数,否则答案为 \(0\)。
D
明显长度奇偶决定取否。
首先想到一定是二进制最高位尽量高,所以,观察样例发现大样例答案是 \(2^k-1\),凑凑 \(8\) 的答案,发现是 \(8\) 段长为 \(1\),于是猜测当长度为 \(2^k\),输出长度(除 \(2\)),否则输出范围内最大的 \(2^k-1\)(除了 \(3\)),验证发现可以构造。
P2018
\(N\) 个点的树,可以给其中一个上色,每一个单位时间,已上色单位可以将连向的一个点上色,求给所有节点上色的最短时间和哪些节点可以实现。
\(N\le 10^3\)。
以每个结点为根进行一次 \(O(n)\) 的树形 DP。
对于每个节点,统计以它为根的子树的答案,用儿子更新父亲。
考虑贪心,将儿子的答案从大到小排序,先走大的,所以 \(f_u=min\{f_v+ord_v\}\),\(v\) 是 \(u\) 的儿子,\(ord_v\) 是排序后 \(v\) 在第几个位置。
2025.8.11
- 找题做
- 陪 tsy 板刷 *\(2000\)。
P2441
给定一棵 \(N\) 个点的树,\(k\) 次操作,一种是更改一个点的点权,一种是求最近的点权和这个点公因数不为 \(1\) 的祖先。数据随机。
\(N\le 2\times 10^5, k<10^5\)。
由于数据随机,暴力即可。
P4752
给定两个数组 \(a,b\),长为 \(N,M\),求 \(\frac{\Pi_{i=1}^n a_i}{\Pi_{i=1}^m b_i}\) 是否为质数。\(b\) 中的数出现次数小于等于 \(a\)。
\(1\le N\le 10^5,0\le M\le N,1\le a_i,b_i \le 10^{12}\)。
只有剩一个数才有可能,能消的都消掉,最后暴力验质数。
CF2114F
执行若干次操作使 \(x\) 变成 \(\frac{x}{a}\) 或 \(ax\),\(1\le a\le k\),求 \(x\) 变成 \(y\) 的最少次数。
\(1\le x,y,k\le 10^6, \sum x,\sum y\le 10^8\)。
首先去掉 \(\gcd\)。问题变成把 \(x\) 和 \(y\) 分别除到 \(1\) 的次数。
正解 DP,把非因数去掉,对答案没有贡献。
也可以记搜,注意剪枝,当 \(x\) 小于 \(k\) 时直接返回 \(1\)。
剪枝复杂度很难直接证明,可以从 DP 的角度思考,毕竟记搜是从 DP 变过来的。硬要想就是这样剪枝在 \(k\) 大的时候很有效,否则不会有太多数需要计算。
CF379F
初始有一颗四个节点的树,以 \(1\) 为根,\(2,3,4\) 都是 \(1\) 的儿子。进行 \(M\) 次操作,每次指定一个叶子,加两个儿子,求每次加完后的直径。
\(1\le M\le5\times 10^5\)。
每次要更新肯定是用以前直径的一段和新儿子一起,直接离线先建好树,倍增求距离比较即可。
P3369
见 此处。
2025.8.12
- FHQ。
P6136
同 P3369。
P1486
维护一个可重集合,四种操作,总共进行 \(n\) 次,一个下线参数 \(k\)。
- 加入一个值,如果大于等于 \(k\)。
- 给集合中所有数加上一个值。
- 给集合中所有数减去一个值,删除所有小于下线的值。
- 求出集合中第 \(k\) 大的值。
\(0\le n\le 3\times 10^5\)。
对于加减,我们需要在每次减的时候把树分裂一下,左边统计答案,右边成为新树。
由于是全局加减,所以我们只需要用一个变量来统计加了多少,同时修改一下插入的值,使其加上这个变量后是真实值。
其他操作就是模板平衡树了。
B4273
给定 \(N\) 列方格,第 \(i\) 列堆积 \(a_i\) 个方格,求最大矩形面积。
\(1\le N\le 10^6,1\le a_i\le 10^4\)。
复习单调栈板板题。
做法是枚举每列,算出以当前列为高,长拓宽到左右第一个高度小于当前列的,取最大值。
找左右第一个小于就是典型的单调栈。
正确性:如果一个矩阵的高没有顶满任意一列,那么明显可以再加高直至被顶住,所以可以枚举在哪里被顶住。
2025.8.13
- 被炸蒙,开始疯狂。
B3611
传递闭包模板题,知道传递闭包的概念就可以做了,不过还是了解一下为好。
P10938
给定一张 \(n\) 个点 \(m\) 条边的有向无环图,若每条路径上只能选一个点,求最多能选几个点。
\(1\le n\le 200,1\le m\le 3\times 10^4\)。
根据抽屉原理,我们很容易知道把图分成最少数量的路径后,每条路径上最多有一个点,所以答案小于等于最小可重路径覆盖。
而如果在某条这样的路径上不放点,显然是不优的,放到路径上不会造成不合法,仔细想想不同的情况就会发现要么会导致可以合并两条路径,要么可以重新构造路径使其合法。
所以答案就是最小可重路径覆盖。
著名网络流题 P2764 是最小不可重路径覆盖,所以我们需要把这个问题转换一下。其实可不可重的主要问题可以用一个小样例展示。
5 4
1 2
2 3
4 2
2 5
所以我们的主要问题是把 \(4\) 和 \(5\) 连起来,那么我们可以使用传递闭包,及不会影响答案,也能解决这种情况,然后跑网络流即可。
UVA 11526
数论分块真正的模板。
2025.8.14
CF449B
给定一张无向图,\(n\) 个点,\(m\) 条边,给出 \(k\) 条由 \(1\) 连出的特殊边,求最多删除多少条特殊边可以保持从 \(1\) 出发到所有点的最短路不变。
\(1\le n\le 10^5,1\le n\le 3\times 10^5,1\le k\le10^5\)。
很容易想到如果一条特殊边连向的点不是唯一最短路,那么就可以被删除,容易证明对其他点的结果没有影响,所以跑最短路并计数。
CF1311D
给定三个整数 \(a,b,c\),每次操作可以对其中任意一个加一或减一。求最少操作次数,使得 \(a|b\) 且 \(b|c\)。
\(1\le a,b,c \le 10^4\)。
观察到数据较少,考虑枚举一个。
枚举 \(b\) 可以同时确定 \(a\) 和 \(c\),\(a\) 一定是最近的 \(b\) 的因数,\(c\)一定是最近的 \(b\) 的倍数,所以预处理范围内所有数的因数,枚举二分即可。
2025.8.19
- 回学校了,打模拟赛。
P5954 & P5191
模拟赛 A,场切蓝开心😊。题解。
2025.8.20
- 补模拟赛,题解。
- 找题做。
P6877
一个长为 \(n+1\) 的序列 \(A\) 和一个长为 \(n\) 的序列 \(B\),可以对 \(B\) 中每个数进行任意次数的 \(\pm 1\),对于每一个 \(A\) 中的数,求将其删除后能使 \(A\) 和 \(B\) 排序后相同每个数的 \(+1\) 次数最大值最小是多少。
\(1\le N\le 2\times 10^5\)。
题意简述可能有些不清,建议看原题。
发现将两个原序列排序后一一对应地变化是最优的,所以排好序后枚举去掉的数,预处理一下就行。可以看代码。
2025.8.21
- 打模拟赛,补模拟赛。
- 做题。
B4169
板子线段树。
2025.8.22
- 补模拟赛 C。
- 整理中山的知识点。
2025.8.23
- 做高维前缀和和 SOS dp 的题单。
- 打 duel。
P5495
给定大小为 \(n\) 的数组 \(a\),求所有 \(b_i = \sum_{j|i} a_j\) 的异或和。
\(1\le n \le 2\times 10^7\)。
因为 \(j|i\),所以 \(j\) 的所有质因子的次数都要小于等于 \(i\) 的,那么也就相当于前缀和中的每一维都小于等于当前这一个位置的所有和。所以就是一个每一维维护一个质因子的个数的前缀和。
实际上递推时,由于每次只需要用一个质因子来递推,所以我们可以直接用这个位置对应的数(所有质因子按指数乘起来的结果)来代替,可以在埃筛时递推,具体见代码。
ARC136D
给定一个大小为 \(n\) 的数组 \(a\),求 \((i,j)(i<j)\) 的对数使得 \(a_i\) 和 \(a_j\) 在相加时不会进位。
\(2\le n\le 10^6,0\le a_i\le 10^6-1\)。
只有 \(6\) 位,可以用每一维记录每一位,还是可以压成一个整数,好写,把每个 \(a_i\) 的位置标记后前缀和,然后对于每一个 \(a_i\),能和它配对的就是 \(s_{999999-a_i}\),也就是和 \(a_i\) 加起来每一位都小于等于 \(9\) 的数的个数。
CF165E
给定一个长为 \(n\) 的数组 \(a\),对于每一个 \(a_i\) 求一个 \(a_j\) 使得 \(a_i \land a_j=0\)。
\(1\le n\le 10^6,1\le a_i\le 4\times 10^6\)。
和上面这题是类似的,也就是说对于每一位,加起来都不进位。记录每一段前缀满足条件的 \(a_j\)。
CF1120A
见洛谷题解。
CF1157C2
一个长为 \(n\) 的数列 \(a\),每次可以取走左右两端的其中一个数,要求取出数的数列满足严格单调递增,求最多能取出多少数以及输出任意方案。
\(1\le n,a_i\le 2\times 10^5\)。
比较显然的贪心,都能选的话肯定选小的,这样还能选另一个,不影响。
注意相同的情况,因为选了一个另一边就封死了,所以只能一条路走到底,预处理看哪边更长就行。
这题252个点,230个都是 hack。
2025.8.25
- 继续题单。
CF383E
给出 \(n\) 个长为三的字符串,包含字符
a到x,对于每一个字符a到x的子集,求出有多少个字符串中包含至少一个子集中的字符。输出所有答案的平方的异或和。\(1\le n\le 10^4\)。
正难则反,没想到啊。
变成有多少个字符串被子集完全不包含,容易发现这和原答案恰好互补,而完全不包含又和完全包含相同。
每一维记录一个字母在不在子集中,递推被这个子集完全包含的字符串个数。使用状压进行简化。
ARC100C
给定一个长为 \(2^n\) 的数列 \(a\),下标从 \(0\) 开始。对于每一个 \(1\le k\le 2^n-1\),求 \(\max_{i|j\le k}\{a_i+a_j\}\)。
\(1\le n\le 18\)。
第一时间想到的状态数组应该是或起来小于等于 \(k\) 的,但是不好做,因为两个小于 \(k\) 的数可以或出大于 \(k\) 的。
所以我们记录每一位小于等于 \(k\) 的,这样保证不会超,至于其中实际没达到 \(k\) 的也不会多统计。
注意要同时记录最大值和次大值,加起来才是结果。
最后前缀最大值就是答案。
2025.8.26
- 继续做题单。
- 做做真题题单。
P6442 & SP13106
\(n\) 个箱子,\(m\) 种玩具,已知每个箱子里有哪些种类的玩具,求有多少种选箱子的方案能包含所有种类的玩具。
\(1\le n \le 10^6,1\le m\le 20\)。
\(s_i\) 表示包含玩具状态是 \(i\) 的子集的有多少个。
\(f_i\) 表示选出若干个箱子并集是 \(i\) 的子集的有多少种方案。
显然 \(f_i = 2^{s_i} - 1\)。(wssb没想到)
但是要求的是刚好等于的,所以我们 高维差分 一下,操作和前缀和差不多。
P7912
给定一个长为 \(n\) 的 01 数组 \(a\),进行若干轮操作,每次输出每个连续的相同数字段的第一个在原数组中的下标,将其删除,直到数组为空。
\(1\le n \le 2\times 10^5\)。
奇奇怪怪做法挺多的,介绍一种。
用两个 set 分别维护 \(0/1\) 的下标,每次看从哪个开头,然后在两个 set 之间反复交替找位置更靠后的一个,输出删除,既保证不是连着两段,又保证顺序。
P2672
两个长为 \(n\) 的数组 \(a\) 和 \(b\),对于每一个 \(1\le k \le n\) 求从中选出恰好 \(k\) 个下标时的 \(2\times\max_{i\in s}\{a_i\}+b_i\),下标集合为 \(s\)。
\(1\le n\le 10^5\)。
很久以前做的,怀疑那时候不太懂。复习一下。
考虑贪心,选出 \(b_i\) 最大的 \(k\) 个,这是可以作为答案的。但是有可能选一个 \(a_i\) 大于这 \(k\) 个的,并且只会选一个,不难证明。选两个也只有一个 \(a_i\) 有效。同时可以注意到替换的肯定是 \(b_i\) 最小的。
没有其他情况,所以我们只需要统计这两种情况的答案就行了。
先按 \(b_i\) 从大到小排序,用一个前缀和数组 \(s_k\) 记录前 \(k\) 大的 \(b_i\) 的和。
用一个数组 \(fl_i\) 记录前缀 \(2a_i\) 最大值,另一个数组 \(fr_i\) 记录后缀 \(2a_i+b_i\) 最大值,表示替换一个的情况。
于是答案就很好求了:\(ans_i=\max(fl_i+s_i,fr_{i+1}+s_{i-1})\)。
2025.8.27
- 做真题题单。
P1982
给定长为 \(n\) 的序列 \(a\),求最大的 \(s_i\),
\[s_i=\max_{1\le j< i}\{s_j+f_j\} \]其中 \(s_1=f_1\),\(f_i\) 表示序列 \(a\) 中前 \(i\) 个数的最大子段和。答案对 \(p\) 取模。
\(1\le n\le 10^6,1\le p\le 10^9,-10^9\le a_i\le 10^9\)。
\(f\) 是很好求的,最大子段和 dp 一下,求个前缀最大值就行,那么 \(s\) 也很好求了。注意需要 __int128。
2025.8.28
- 打模拟赛。
模拟赛笔记
T1(CF1011F)
考虑每个叶子往上这条链,到头走不动要么是影响了根,要么是因为变化对于某个运算无效。
对于每一个点,分讨一下左右儿子变化有没有影响就行,如果一个节点变化影响不了父亲,那么子树内所有叶子变化全都无效,遍历下传标记即可。
P1053
一个 \(n\) 个点的环,每次可以选择若干个点轮换一次,要求变成某个环,求每次选择的点数的和的最小值。
\(3\le n\le 50000\)。
需要注意到,由于可以乱换(换的点的位置和顺序),那么把一部分互相连锁的点换一下就全匹配上了,所以只有原本位置不对的点要换,我们只需要考虑对于每一种环的对应关系,也就是把这个环对称或旋转,最多能匹配上多少。可以用桶记录偏移量。
2025.8.29
- 写树网的核没调完。
2025.8.30
- 打模拟赛。
模拟赛笔记
T1
不知道怎么一眼了,感觉不难。发现可以通过让某两段的长度为 \(1\) 使得答案最多只有 \(3\)。进一步观察发现答案只可能是 \(0,1,3\),然后想到找得到三个不同开头就是 \(0\),三个都只能相同就是 \(3\),否则是 \(1\)。
8 月结束了,开学了,第一次写这么长的文章,也是第一次写这种类型的文章。完结撒花。
9 月链接。

浙公网安备 33010602011771号