Loading

2026 寒假集训题目

qoj10518 腐蚀与膨胀:

https://qoj.ac/problem/10518

注意到某些操作可以复合,例如:

\[(0,a)+(0,b)=(0,a+b) \]

\[(0,a)+(1,b)+(0,c)=(0,a+c-b),\min(a,c)\ge b \]

如此操作我们就可以把总共 \(q\) 次操作变成 \(O(n)\) 次操作,然后暴力做就行了,时间复杂度 \(O(n^3)\)

qoj10519 萤火虫难题:

https://qoj.ac/problem/10519

首先不考虑颜色不同的条件,设 \(f_{i,p}\) 表示考虑到第 \(i\) 个数,其中最后一个被选的数有一个质因子是 \(p\) 最多能选多少个数。

转移就是 \(f_{i,p}\gets f_{i-1, q}+1\),其中 \(p,q\)\(w_i\) 的质因子,滚动数组一下就变成 \(O(n\log n)\) 的了。

在考虑如何加入颜色不同的条件,注意到只需要维护两种不同的颜色就一定有一个满足颜色不同的条件,所以只需要维护最大值的一个颜色,次大值的一个颜色转移即可。

洛谷 - P12976 受力分析 Force:

https://www.luogu.com.cn/problem/P12976

这个不等式的形式和差分约束很像,考虑把 \(x_i\gets -x_i\) 变成减法,限制变为 \(l_{i,j}\le y_j-x_i\le r_{i,j},x_i\le 0,y_j\ge 0\),要求 \([-x_1,-x_2,\cdots,-x_n,y_1,y_2,\cdots,y_n]\) 字典序最小。

先不考虑 \(y\),那么就要求 \([x_1,x_2,\cdots,x_n]\) 的字典序最大。根据经典套路,将 \(0\) 和所有 \(x\) 连一条长度为 \(0\) 的边,其他限制正常建边,从 \(0\) 开始跑最短路,得到的 dis 数组就是字典序最大的方案。

但是这里还有 \(y\),直接求 \(y\) 都是顶到最大的,字典序显然不够小。但是你发现你得到了 \(x\) 最优的方案,由于 \(y\) 直接互不影响,可以直接求出每一个 \(y\) 的范围,每个 \(y\) 取到其下界就是字典序最小方案。

qoj8049 Equal Sums:

https://qoj.ac/problem/8049

【改变顺序缩小值域】:

考虑将 \(x,y\) 分开,分别做两个背包,最后求答案,但是求答案的时间复杂度是 \(O(n^4)\) 的,不可过。

我们发现时间复杂度的瓶颈是算答案的时候枚举背包容量,背包容量是 \(O(n^2)\) 的,\(i,j\)\(O(n^2)\) 都无法优化,考虑压缩背包容量。

考虑将 \(x,y\) 一起处理,设 \(f_{i,j,k}\) 表示选到 \(x_i,y_j\)\(x\) 的和减 \(y\) 的和为 \(k\) 的方案数,我们将 \(k<0\) 的转移到 \(k+x_i\),将 \(k\ge 0\) 的转移到 \(k-y_i\),这样就能实现一一不漏,而且背包容量被压缩到 \(O(n)\),用前缀和优化就行了。

洛谷 - P8991 [北大集训 2021] 出题高手:

https://www.luogu.com.cn/problem/P8991

注意到数据随机,所以区间长度不会很大,假设最大区间长度不超过 \(T\)

那么对 \(r\) 进行扫描线,设 \(mx_l\) 表示左端点为 \(l\) 的区间的最大权值,那么加入 \(r\) 后只需要修改 \(T\) 个位置,暴力修改就行了,查询可以用分块维护,设块长为 \(B\),那么修改为 \(O(1)\),查询为 \(O(B+\frac nB)\),若 \(B=O(\sqrt n)\) 那么总时间复杂度是 \(O(nT+n\sqrt n)\)

这个 \(T\) 可能要微调一下。

CF1270F Awesome Substrings:

https://www.luogu.com.cn/problem/CF1270F

\(1\) 的个数的前缀和为 \(s_i\),那么题目转化为 \(r-l=k(s_r-s_l),k\in\mathbb Z\),正常做法都不好做,考虑根号分治。

\(k\le B\),考虑枚举 \(k\) 求答案,\(r-ks_r=l-ks_l\),直接用桶维护数量就可以了,时间复杂度 \(O(nB)\)

\(k>B\),那么 \(s_r-s_l\) 就很小,即区间内 \(1\) 的个数很小。直接枚举左端点每次往后找 \(1\),这一步可以维护 \(nxt\) 数组实现,然后要区间求 \(k\) 的倍数的个数,也可以做到 \(O(1)\),时间复杂度 \(O(\frac{n^2}B)\)

\(B=O(\sqrt n)\) 时,总时间复杂度最低为 \(O(n\sqrt n)\)

CF1039D You Are Given a Tree:

https://www.luogu.com.cn/problem/CF1039D

首先考虑如何对于一个 \(k\) 快速算答案。从下往上贪心记录 \(mx_i\) 表示从 \(i\) 开始的最长链长,对于点 \(i\),如果存在其两个儿子 \(mx_i+mx_j+2\ge k\),那么就将答案加一并将 \(mx\) 归零,再如果他有一个儿子 \(mx_i+1\ge k\) 那么也将答案加一将 \(mx\) 归零,否则就将 \(mx_i\) 设为其儿子的最大 \(mx\)\(+1\)。这样就可以 \(O(n)\) 算一个 \(k\) 的答案了。

继续注意到答案肯定小于等于 \(\lfloor\frac nk\rfloor\),所以答案的种类数不超过 \(O(\sqrt n)\),考虑直接二分找到分界点,时间复杂度 \(O(n\sqrt n\log n)\)

这样复杂度还是太高了,我们发现直接二分是很浪费的,二分处理长段很优,可以将 \(O(len)\) 变成 \(O(\log n)\),但是面对短段,查询次数就会从 \(O(1)\) 变成 \(O(\log n)\) 还变劣了。所以我们考虑分块,块长为 \(B\),我们先暴力算出前 \(B\) 个数的答案,对于后面的答案用二分处理,那么时间复杂度是 \(O(nB+\frac{n\log n}B)\),当 \(B=O(n\sqrt{n\log n})\) 时,总时间复杂度最小为 \(O(n\sqrt{n\log n})\),这个复杂度就可以接受了。

卡常小技巧:不要 dfs,将 dfn 排序,循环遍历算答案。

洛谷 - P9047 [PA 2021] Poborcy podatkowi:

https://www.luogu.com.cn/problem/P9047

【等概率随机 \(\{-1,1\}\) 的序列的前缀和 \(\max\)\(O(\sqrt n)\) 的】:

首先设 \(f_{i,0/1/2/3}\) 表示从 \(i\) 开始往下的链的长度为 \(0/1/2/3\) 的最大权值。

转移是 \(f_{i,0}+f_{j,2}\)\(f_{i,1}+f_{j,1}\),或者 \(f_{i,3}\) 单独贡献,但是这里 \(f_{i,0}+f_{j,2}\)\(f_{i,1}+f_{j,1}\) 要枚举 \(i,j\) 导致复杂度变成 \(O(n^2)\),所以考虑把其加入状态中,我们只关心 \(0,2\) 选的个数之差和 \(1\) 的奇偶性。

设计状态 \(g_{i,d,0/1}\) 表示选到第 \(i\) 个儿子,\(c(0)-c(2)=d\)\(c(1)\bmod 2=0/1\) 的最大权值,直接转移值域 \(d\) 会很大,复杂度仍然是 \(O(n^2)\) 的。

但是注意到随机打乱儿子顺序,将 \(0\) 看成 \(1\),将 \(2\) 看成 \(-1\),那么最大前缀和是 \(O(\sqrt n)\) 的,所以值域就缩小到 \(O(\sqrt n)\) 了,时间复杂度也就变成了 \(O(n\sqrt n)\) 的了。

洛谷 - P9261 [PA 2022] Płótno:

https://www.luogu.com.cn/problem/P9261

【平面图欧拉定理】:

求连通块个数,让我们想到用平面图欧拉定理进行容斥计算(森林的点-边容斥也是这个道理)。我们将相邻的黑块连边,就会得到一张图,若黑块没有连成一个大环那么图就是一张平面图。

先考虑没有连成大环的情况,使用平面图欧拉定理 \(V-E+F=C+1\),其中 \(V\)\(1\times 1\) 的黑块个数,\(E\)\(1\times 2,2\times 1\) 的黑块个数,\(F\)\(2\times 2\) 的黑块个数加一,综上可以得出连通块个数为 \(c(1\times 1)-c(1\times 2)-c(2\times 1)+c(2\times 2)\)。考虑对 \(r\) 扫描线,设 \(a_l\)\([l,r]\) 的连通块个数,那么就需要支持前缀 +1/-1,全局查值域在 \([1,k]\) 中的数的个数,直接用分块做就行了,时间复杂度 \(O(n\sqrt{nk})\)

如果连成大环,注意到算出来的答案一定是 \(0\),所以最后将 \(ans_1\gets ans_1+ans_0\) 就行了。

洛谷 - P7525 Shelter:

https://www.luogu.com.cn/problem/P7525

注意到如果 \(s\) 没有整周期,那么其 border 在 \(O(\log n)\) 次操作后就不会变了,那么直接暴力做就行了。

如果有整周期,那么就是一个等比数列求和。

这道题空间卡的比较死,只能用 hash 求 border。

loj6515 「雅礼集训 2018 Day10」贪玩蓝月:

https://loj.ac/p/6515

【双栈模拟队列】:

我们用两个栈模拟双端队列,加元素直接在对应栈内 push,删元素如果栈还没空就直接 pop,否则将所有元素平分到两个栈中。证明考虑设势能 \(\Phi\) 为两个栈的元素个数之差,每次 push 和 pop 最多会让 \(\Phi\) 增大 \(1\),然而重构操作会花费 \(\Phi\) 的时间将 \(\Phi\) 清零,所以总时间复杂度是 \(O(n)\) 的。

这里考虑维护两个栈的背包数组,push 和 pop 可以做到 \(O(p)\),重构也可以做到 \(O(\Phi p)\),最终求答案的时候合并背包用单调队列即可,总时间复杂度 \(O(np)\)

但是我最后写的是 \(O(np^2)\) 的做法,加上取模优化就过了。

qoj8147. Math Exam:

https://qoj.ac/problem/8147

【两条线的格路计数】:

首先得到 \(a_1=1\),然后使用作差法,得到:\(4a_i=(a_i+1)^2-(a_{i-1}+1)^2\),解得 \(a_i=a_{i-1}+2\)\(a_i=-a_{i-1}\)。设 \(b_i=\frac{|a_i+1|}2\),那么就有 \(b_1=1,b_i=b_{i-1}\pm 1\),还要满足范围 \(0\le b_i\le\frac{m+1}2\)

这个形式就是两条线的格路计数,参见 格路计数

AT_agc002_f [AGC002F] Leftmost Ball:

https://www.luogu.com.cn/problem/AT_agc002_f

原题条件不好做,考虑转化条件。有 \(k\) 个白球,其余颜色的球各 \(k-1\) 个,对于任意前缀需要满足其他颜色种类数不超过白球数量才合法。

\(f_{i,j}\) 表示用了 \(i\) 个白球和 \(j\le i\) 种其他颜色的求的方案数,转移考虑从左往右的第一个空位置放什么。

第一种情况是放白球,肯定合法,\(f_{i,j}\gets f_{i-1,j}\)

第二种情况是放其他颜色的球,从 \(f_{i,j-1}\) 转移过来,先从 \(n-j+1\) 个球中选出一个颜色放进去(肯定是合法的,因为保证了 \(j\le i\)),接着在 \(nk-i-(j-1)(k-1)-1\) 个空位中插入 \(k-2\) 个球,所以转移是 \(f_{i,j}\gets (n-j+1){nk-i-(j-1)(k-1)-1\choose k-2}f_{i,j-1}\)

边界就是 \(f_{0,0}=1\)

qoj3744 HNCPC 2018 F. Fixed Point:

https://qoj.ac/problem/3744

先求出 \(m\) 次操作后的置换,将询问按照 \(k\bmod m\) 分类,\(k/m\) 就是在置换环上走的距离,是否能走到 \(i\) 就只和他与 \(i\) 在置换环上的距离有关,只要 \(k/m\) 模置换环长度等于这个数就满足条件。

注意到置换环长度之和为 \(n\),所以本质不同的置换环长度个数只有 \(O(\sqrt n)\) 种,所以直接 \(O(n)\) 预处理后 \(O(\sqrt n)\) 暴力查询即可。时间复杂度:\(O(nm+q\sqrt n)\)

洛谷 - P8512 [Ynoi Easy Round 2021] TEST_152:

https://www.luogu.com.cn/problem/P8512

先考虑 \(L=1,R=n\) 怎么做,直接颜色段均摊,用 set 维护每个颜色段,过程中维护答案就行了。

如果有多组询问,考虑对 \(R\) 扫描线,我们发现如果现在维护出了 \(1\sim R\)set,那么只需要去掉 \(1\sim L-1\) 贡献了的区间就是 \(L\sim R\)set,所以我们用树状数组维护第 \(i\) 次操作的贡献,每次查询就是查后缀和,总时间复杂度 \(O(n\log n)\)

CF1922F Replace on Segment:

https://www.luogu.com.cn/problem/CF1922F

注意到每次操作都不相交。

\(f_{i,j,k}\) 表示区间 \([i,j]\) 全部变成 \(k\) 的最小操作数,\(g_{i,j,k}\) 表示区间 \([i,j]\) 全部变成非 \(k\) 的最小操作数,初始化显然。

一种转移是进行一次操作:

\[f_{i,j,k}\gets g_{i,j,k}+1 \]

\[g_{i,j,k}\gets g_{i,j,l}+1,k\neq l \]

第二种转移就是两个区间合并:

\[f_{i,j,k}\gets f_{i,m,k}+f_{m+1,j,k} \]

\[g_{i,j,k}\gets g_{i,m,k}+g_{m+1,j,k} \]

转移有环,多转移几次就行了。

洛谷 - P14829 [THUPC 2026 初赛] Asian Soul:

https://www.luogu.com.cn/problem/P14829

发现答案可以拆分,所以考虑线段树,将询问离线下来做线段树分治。

为了方便,设 \(a\) 为 1 类点,询问为 2 类点。对于每个线段树上的节点,建出 1/2 类点的虚树,考虑枚举 lca 为点 \(u\)\(u\) 会对什么点做出贡献。设 \(v\)\(u\) 的一个儿子,\(s_i\) 表示 \(i\) 子树内(虚树)有多少个 1 类点,如果 \(s_u>s_v\),那么 \(u\) 就可以贡献到 \(v\) 的子树中的所有点上,递推维护 \(mx_i\) 表示 \(i\) 被贡献的最大值即可。时间复杂度 \(O(n\log^2n)\)

卡常小技巧:

  1. 不要写 dfs,写迭代会更快。
  2. 做法的瓶颈在建虚树的排序上,使用单调栈建虚树,然后归并排序就可以做到 \(O(n\log n)\)

感觉不如 guanyf 一只 log 跑的没我两只 log 快。

洛谷 - P3188 [HNOI2007] 梦幻岛宝珠:

https://www.luogu.com.cn/problem/P3188

数据范围中每个物体的体积都可以写成 \(a\times 2^b\) 的形式且 \(a\le 10\),这启发我们对 \(b\) 进行分类,先对每种 \(b\) 做一次背包再合并。

合并就是从每个组内选出一部分容量去背包,和 P7961 类似,设 \(f_{i,j}\) 表示从高往低考虑到第 \(i\) 位,还剩多少容量,扩散转移即可。

posted @ 2026-02-03 22:25  liruixiong0101  阅读(75)  评论(0)    收藏  举报