2024 年 8 月做题记录
做题记录 (2024/8)
一些难题/好题/做完比较有感触的题会写进来。每月一篇,不定时更新。
难度评分:思维/代码,满分 \(10\)。
不保证作为题解是合格的。
题面可以从 submission 点进去看。
注:NOIPSC = NOIP simulation contest
CF1991F. Trangle Formation
Difficulty: \(3.5/2\)
考虑怎样的序列一个三角形也不能构成。
考虑两根长为 \(1\) 的木棍,则下一根长度 \(\ge2\),再下一根 \(\ge3\),在下一根 \(\ge5\)……于是第 \(i\) 根的长度最小值是斐波那契数列的第 \(i\) 项。这玩意是指数增长的,不到 \(50\) 项就会爆出 \(10^9\)。
这时再随便来几根就可以组成两个三角形了(理论最小值是 \(t=48\) 根)。所以 \(r-l+1\ge t\) 的时候直接 ok 了。
考虑 \(r-l+1<t\) 怎么做。结论是排序后这两个三角形要么是两组分开的连续三个,要么是连续六个。暴力即可。时间复杂度 \(\Theta(q(t\log t+\binom 63t))\)。
CF1991I. Grid Game
Difficulty: \(8/7\)
神仙交互题,咕。
P2482. [SDOI2010] Pig Kingdom War
Difficulty: \(1/9\)
题目本身没啥好说的。大模拟。调了 \(\texttt{3h}\),写了 \(\texttt{5KB}\)。以下是我的一些唐氏 bug。
- 一个人出决斗结果自己似了,然后他继续出牌?
- check 任何东西的时候请跳过似人。
- 决斗可以和任何人决。
- 反贼不会决忠臣(只会决主公)。
- 不能只通过身份确定是否要无懈(例如,主公会无懈类反贼)。
- 决斗只在开始时可以被无懈,但南蛮/万箭是在判每个人之前 check 无懈,并且只对他自己有效。
AGC066B. Decreasing Digit Sums
Difficulty: \(5.5/3\)
讲个笑话:本人在该场中 \(\texttt{3h}\) 切了 \(0\) 题,但是开了 unrated
一般来说数字越来越大数位和也会有越来越大的趋势。所以需要一些观察。
考虑 \(5^{50}\) 的倍数。注意到 \(f(5^{50}\cdot2^i)=f(10^i\cdot5^{50-i})=f(5^{50-i})\),相当于数字会变得越来越小。这是我们想要的。
但是只取一个数还是不行的。根据大数定律,数字越大,下降的趋势就会越明显。考虑随一堆 \(5^{50}\cdot i\) 拼起来,中间用 \(0\) 隔开以免进位产生影响。这样大概就能很快随出来。实测取 \(100\) 个可以秒出解。把数直接交上去就行了。
NOIPSC14B. Add Number / ARC153D. Sum of Sum of Digits
Difficulty: \(4/4.5\)
进位不太好处理,考虑数位 dp。直接枚举每个数是否进位显然不行,注意到后 \(i\) 位产生进位只能是后 \(i\) 位最大的若干个数。于是设 \(dp_{i,j}\) 表示后 \(i\) 位中,最大的 \(j\) 个数产生进位的最小代价。转移枚举下一位数字填啥就行了。
如果直接转移需要 \(\Theta(n)\) 计算状态和值。双指针优化即可做到(均摊)\(\Theta(1)\) 转移。
总复杂度 \(\Theta(n\log_\Sigma V(\log n+\Sigma))\)。\(\log n\) 可以基数排序省掉但是没必要。
NOIPSC13B. Jiangqiao Escaping on Tree / P3006. [USACO11JAN] Bottleneck G
Difficulty: \(6/4\)
没理解透。还要回来看。
首先发现人够的话到父亲的边永远是灌满的。人不够了就永远灌不满了。
所以可以分成两个阶段,而分界点就是 \(\dfrac{\text{初始人数}}{\text{净输出量}}\)。
一旦灌不满了,它连向父亲的边就没用了。可以把它和父亲合并起来。
然后因为某些神仙原因可以直接把它的净输出量和初始人数全部加到他父亲上就行了。再在并查集上合并两点即可。
询问在每次阶段变化中间就可以顺便回答了。变化时间可以 pq 维护。时间复杂度 \(\Theta(n\log n+q\log q)\)。
NOIPSC14C. Coloring Plans
Difficulty: \(5/3\)
这题赛时差不多已经想出来但没时间写了。主要是赛时胡了好几个假做法。。。
限制就是一个点能到的点构成的生成子图所有环长都是偶数。枚举所有限制的话可以用 dfs 树,一条非树边就会加一个限制,一共最多 \(\Theta(nm)\) 个。处理限制可以线性基,用 bitset
,每个限制可以做到 \(\Theta(\frac{m^2}w)\)。
总复杂度 \(\Theta(\frac{nm^3}w)\),但是跑不满一点。跑得嗖嗖快。
NOIPSC14D. Connecting Vertices / AGC065D. Not Intersect
Difficulty: \(9/2.5\)
大神仙计数题。没理解透。之后回来看。
AGC065C. Avoid Half Sum
Difficulty: \(6/2\)
首先有一个 MO 结论:
有 \(n\) 个物体,第 \(i\) 个物体的质量 \(a_i\) 满足 \(1\le a_i\le i\),且 \(\sum_{i=1}^na_i\) 为偶数。则可以将 \(n\) 个物体全部放入天平的左盘或右盘,使得天平平衡。
做法就是从后往前依次放轻的那边就行了。
然后原题可以转化为给每个位置赋一个重量使得天平无法平衡。
然后你对着结论的证法一顿推,你会推出结论是有解当且仅当存在一个数使得比它小的奇数的个数小于它的值减 \(1\)。直接做就行了。\(\Theta(n\log n)\)。
CF1997F. Chips on a Line
Difficulty: \(3/2.5\)
一眼秒了。不想认真讲。
首先我不知怎么一眼就想到了赋权,然后自然而然想到斐波那契。然后发现 \(f_1=f_2=1\) 完美。
然后 dp 两下就做完了。时间是 \(\Theta(n^2xf_x)\)。
AGC066C. Delete AAB or BAA
Difficulty: \(7/3\)
经过我数小时的打表找规律思考,发现一个串可以删空当且仅当可以划分成若干个满足以下条件的子串:
- \(\texttt A\) 的数量是 \(\texttt B\) 的两倍;
- 两端字符中至少有一个是 \(\texttt B\)。
回到原题,考虑 dp。可以发现只需转移满足上述条件的子串就可以了。随便优化一下就行了。时间复杂度 \(\Theta(n)\)。
P9720. [EC Final 2022] Map
Difficulty: \(5/6\)
不会计算几何啊。。。
以下记 \(f\) 操作为从公园跳到地图,\(g\) 为从地图跳到公园。
首先先 \(g\) 再 \(f\) 不如直接走,不但走的距离大而且浪费两次操作。
那么可以发现,最终一定是先 \(f\) 若干次,然后走到某个点,然后 \(g\) 回去若干次。
于是爆枚 \(f,g\) 的次数,算出要走的是从哪到哪,取个 \(\min\) 就行了。时间复杂度 \(\Theta(Tn^2)\)。
NOIPSC15B. Table Tennis
Difficulty: \(5.5/6\)
显然你需要能合并两个胜负序列(的信息),不然根本没法做。
然后赛时我就维护了一坨东西:
假设从该序列的第 \(1/2/3\) 局开始比,最终的大比分、小比分;该序列第 \(1,2\) 局的胜负。
然后合并写了 \(\texttt{1k+}\)。
赛后讲题时的更简洁的维护:
开始时小比分为 \(x:y\) 时,双方获得的大比分之差及最后的小比分。(\(0\le x,y\le1\))
然后直接上倍增就做完了。
由于常数大,代码整整跑了 \(\texttt{1.93s}/\texttt{2s}\)。赛时被 \(u=v\) 的 UB 情况卡了,挂了 \(60\)。正是:
一个
info
码量堆,一个pushup
写 \(\texttt{1K}\)。一个 bug 深藏黑,一个 WA 假算危。
调完 bug 笑嘿嘿,常数巨大时空飞。自信 AC 不会亏,没判 corner \(40\) 归。
NOIPSC15C. Tianji's Horse Racing 2
Difficulty: \(4/3.5\)
先看单组咋做。
可以转化为,对每个 \(a_i\),要找一个 \(b_j\) 使得 \(a_i\le b_j\),问方案数。这是个 trivial 题。注意 \(b_j\) 有重,所以其答案为
然后随便就能维护了。\(\Theta(n\log n)\)。
NOIPSC15D. Game on the Top of Cloud
Difficulty: \(7/6.5\)
神仙题!
首先可以想到一个 dp:
令 \(dp_{i,0\sim10,0/1}\) 表示前 \(i\) 个字符,末尾分别为以下串的方案数/权值和(如有多个符合取最长的):
\(\texttt{A},\texttt{AA},\texttt{B},\texttt{BA},\texttt{BAA},\texttt{a},\texttt{aa},\texttt{b},\texttt{ba},\texttt{baa},\texttt{C}/\texttt{c}/\text{啥都没有}\)。
转移就看一下这个字母取不取,如何合并即可。
直接做大概是 \(\Theta(nqS)\) 的,其中 \(S=11\)。
然后你发现这玩意的瓶颈在于连接俩序列。
你想到了启发式合并,然后你 WA 了。你发现启发式合并会把顺序搞乱。
于是直接 dp 报废。
你发现根本原因是这个 dp 没有结合律,没法直接合并俩 dp 值。于是你考虑用矩阵维护 dp。
你发现能维护了。你用 list
维护每个序列,加一个字符就乘上它的矩阵,减一个字符就乘它的逆矩阵(可以预处理,没有额外常数),连接也可以直接乘了。时间复杂度 \(\Theta((n+q)S^3)\)。
你发现你 TLE 了,因为你的矩阵实际上是 \(2S\) 的(你需要维护方案数和权值和)。你考虑维护 \((\text{方案数矩阵},\text{权值矩阵})\)。你发现这玩意还是能合并的。大概就是:
然后你合并/分裂的代价就从 \(8S^3\) 压到了 \(3S^3\),常数变成了原来的 \(\dfrac38\)。然后你就以 \(\texttt{4.49s}/\texttt{5s}\) 的优秀成绩通过了此题!
ABC365F. Takahashi on Grid
Difficulty: \(?/5.5\)
见过原,所以不予评思维难度。
ABC365G. AtCoder Office
Difficulty: \(5/5\)
考虑对于一组询问,如果之前问过就存 map
里直接答,否则你像启发式合并那样,用段数少的那一边怼段数多的,直接 lower_bound
出来然后算一下贡献。
分析时间复杂度:显然重复询问不优,如果将段数排序为 \(a_1\ge a_2\ge a_3\ge\cdots\ge a_n\),则有:
显然把前面 \(\Theta(\sqrt q)\) 个两两问一次能卡到最高复杂度。此时:
当然 lower_bound
还带一只 \(\log m\),所以总复杂度为 \(\Theta(m\sqrt q\log m)\),但是跑的嗖嗖快,最大点只跑了 \(\texttt{1s}\)。
ABC213H. Stroll
Difficulty: \(4/5\)
很 edu 的题。
首先考虑 dp,设 \(dp_{i,j}\) 为走了的距离为 \(i\),现在在点 \(j\) 的方案数,则有转移:
这显然是一个卷积的形式,但是这里是半在线的。分治 NTT 即可。
时间复杂度 \(\Theta(mT\log^2T)\)。
NOIPSC16C. Jiangqiao's False Data
Difficulty: \(?/2.5\)
打表题。
设 \(f_i\) 表示考虑 \(i\) 个点的方案数。可以通过枚举无出度点的个数来转移,但是系数不好算。
打个表发现可以 \(\Theta(n^2)\) 递推。做完了。
NOIPSC17C. Jiangqiao's 3 Spanning Tree / P3037 [USACO11DEC] Simplifying the Farm G
Difficulty: \(4/3.5\)
把 =
写成 +=
过了赛时所有数据。。。
考虑 Kruskal,可以知道只有权值相同的边才能有调整空间。稍微分讨一下即可。\(\Theta(n\alpha(n))\)。
NOIPSC17D. Jiangqiao's Graph of Graphs / P7293 [USACO21JAN] Sum of Distances P
Difficulty: \(6/5.5\)
这怎么是个黑题啊。模拟赛赛时做法甚至题解区一篇都没有虽然复杂度有点小大。
首先在大图上走相当于每个图上各走一步。
对于一个结点序列,考虑它的最小步数。因为可以通过反复横跳来捏造 \(2\) 步,所以考虑分奇偶性讨论。
每个图 \(i\) 分别 bfs 出 \(1\) 到所有 \(j\),走过步数是奇数/偶数的距离,记为 \(d_{i,0/1,j}\)。那么对于奇数/偶数,距离分别取最大值即可。那么最小的步数就是奇偶步数的最小值。
即,如果分别选取了 \(g_1,g_2,\ldots,g_k\),则距离为:
但是这玩意一个 \(\min\) 一个 \(\max\),不好处理。
考虑以下事实:(简单拆一下贡献即可证明。)
那么可以转化为对每个 \(i\) 求出距离 \(\ge i\) 的 \(g\) 的个数再求和。这时序列就变成了 \(01\) 序列,合法的要求就是奇偶数两边都有 \(1\)。
考虑扫描线,把 \(i\) 从小到大扫,那么就只有把某个 \(1\) 变成 \(0\) 的操作了,然后要维护两边都有 \(1\) 的方案数。
对于一堆序列,可以记 \(f_{00,01,10,11}\) 表示奇数、偶数分别有/没有 \(1\) 的方案数。容易发现合并直接暴力或卷积就行了。
所以线段树维护一下就求完了。(最后记得把走不到的状态的多余贡献减掉)
时间复杂度为 \(\Theta(k\log k+\sum(n+m))\),虽然带了或卷积的 \(16\) 的常数但是只跑了 \(\texttt{124ms}\) 一点也不卡常。
NOIPSC17B. Jiangqiao's Smallest k Costs / P2541 [USACO16DEC] Robotic Cow Herd P
Difficulty: \(7/3.5\)
题解在放什么屁。半懂不懂。
NOIPSC18C. Buying Jewels
Difficulty: \(6/7\)
你发现这玩意有三维状态(时间,价格,结点),考虑离线降维。
整体二分答案,那么就是 check 所有价格小于某个值的能买的东西能否灌满价钱。
维护加删物品的过程,你发现它就是在 \((\)时间\(,dfn)\) 的平面上矩形加/单点查。直接二维线段树即可。
然后你会二分出每个询问能买满的价格。然后判一下是否能买至少一个下一贵的物品就行了。
时间 \(\Theta(n\log^3n)\),代码有点史。
NOIPSC18D. Counting Permutations / CF1988F. Heartbeat
Difficulty: \(7/3.5\)
小神仙题。
首先考虑固定的 \(n\)。如果直接 dp,不管正着还是倒着都会有一个前/后缀最大值不好压进状态。可以枚举 \(n\) 所在的位置,这样前、后缀最大值就无关了,可以分成两部分。
那么设 \(dp_{i,j,k}\) 表示一个 \(1\sim i\) 的排列,有 \(j\) 个前缀最大值,\(k\) 对上升位置,\(i\) 必须在最后的排列数量。转移时,不妨整体加一,再插入一个 \(1\),讨论一下:
- 如果 \(1\) 加在最前面,则前缀最大值、上升位置都加 \(1\);
- 如果 \(1\) 加在一对上升位置中间,则它们都不变;
- 如果加在一对下降位置中间,则上升位置数加一。
据此可以实现转移。
考虑计算答案,注意到 \(n\) 后面其实就是 \(dp\) 出来的排列翻转了:
这玩意直接算是 \(\Theta(n^6)\) 的,妥妥炸飞。
然后后面的优化就很神仙了。令
,这俩数组是能 \(\Theta(n^3)\) 算的。然后把 \(i+j=n+1\) 代进去,\(\mathrm{ans}_n\) 就被表示成了:
然后发现还能压:
然后:
做完了。时间复杂度 \(\Theta(n^3)\)。滚动数组把空间压到 \(\Theta(n^2)\)。注意常数。(在 CF 上交的时候记得选 64bit)
NOIPSC19D. Jiangqiao's Segments / P3050 [USACO12MAR] Large Banner G
Difficulty: \(5/4\)
莫反经典套路题,咕。
ARC105E. Keep Graph Disconnected
Difficulty: \(5.5/2\)
好题。
考虑最后加不动边时的图,可以发现一定是 \(1\) 和 \(n\) 分别在两坨点组成的团里。它有多少条边呢?假设其中一坨有 \(i\) 个点:
可以发现,如果 \(n\) 是奇数,那么最后边数的奇偶性是固定的,胜负已分。
如果 \(n\) 是偶数,那么其中一个人就会死命让 \(i\) 变成偶数,另一个人死命让 \(i\) 变成奇数。
考虑此时的胜负关系。
写不下去了 T_T,反正就是考虑一下镜像操作,
结论就是如果先手死命抢偶数,那么当且仅当 \(1\) 和 \(n\) 所在连通块大小至少有一个是偶数时先手赢;如果先手死命抢奇数,那么当且仅当有一个是奇数时先手赢。
NOIPSC21D. Skiing
Difficulty: \(6.5/6\)
首先发现可以 dp。转移顺序:以到根距离升序为第一关键字,再按 \(d_i\) 降序为第二关键字。
但是一个点能够转移到很多个点,太慢了。
注意到转移的限制就是 \(\mathrm{dist}(x,y)\le d_x\),这种路径长度的问题就很能点分治。
由于转移要求在线处理,考虑建点分树。计算一个点的 \(dp\) 值时,直接遍历它和它在点分树上的祖先,每个结点按到其的距离从小到大建线段树,那么就是单点改区间 \(\min\),做得了一点的。
由点分树的性质可以知道这是对的。时间复杂度 \(\Theta(n\log^2n)\)。
ABC366G. XOR Neighbors
Difficulty: \(4/3\)
唐题,但是赛场硬控我 1h((
考虑每个点分一个 bit,然后就会有一堆限制条件,随便高消一下就得了。
以下代码时间复杂度为 \(\Theta(\frac{n^4}w)\)。
ARC182C. Sum of Number of Divisors of Product
Difficulty: \(6/3.5\)
赛时硬控我 1.5h 的题。
首先乘积中只可能有 \(2,3,5,7,11,13\) 这几种质因数。设它们各有 \(a,b,c,d,e,f\) 个,则因数个数为 \((a+1)(b+1)(c+1)(d+1)(e+1)(f+1)\)。
这个式子有另一种解释:
有六堆球,分别有 \(a\)、\(b\)、\(c\)、\(d\)、\(e\)、\(f\) 个,从每堆中各取至多一个,问方案数。
这样我们就能状压 dp 了。设 \(dp_{i,S}\) 表示前 \(i\) 个数中已经从 \(S\) 里各取了一个球的方案数。转移是简单的。
发现每层的转移都是一样的,于是矩阵快速幂优化即可。时间复杂度 \(\Theta(8^{\pi(m)}\log n)\)。
P10855 「Cfz Round 4」Gcd with Xor
Difficulty: \(6/4.5\)
莫反好题。咕。
NOIPSC22D. Jiangqiao's Village construction
Difficulty: \(6/4.5\)
咕。