2025/12 做题记录

  1. P14636 NOIP2025 清仓甩卖 / sale

    考虑这个策略为啥会爆。发现当选取了一段价值和为 m-1 的前缀之后,就只能取接下来的一个 1 了。但是如果这个前缀后面的 2 可以代替这个 1,以及前缀中价值最小的 1,那么就爆了。考虑刻画这个性质。假设 \(a_k\) 代替了 \(a_i\)\(a_j\)。那么我们枚举 \(i\)\(k\)。将所有物品归类为以下几类:

    如果 \(w\)\(1\) 的时候在 \(i\) 前面,\(w\)\(2\) 的时候仍然在 \(k\) 前面,那么称之为 A 类。对前缀可能造成 +1/+2 的贡献。

    如果 \(w\)\(1\) 的时候在 \(i\) 前面,\(w\)\(2\) 的时候在 \(k\) 后面,那么称之为 B 类。对前缀可能造成 +0/+1 的贡献。

    如果 \(w\)\(1\) 的时候就在 \(j\) 的后面,那么只要把方案数乘上 \(2\) 即可。

    我们希望对 A 类和 B 类物品进行选择,使得和为 \(m-2\)。容易发现只要知道 A 类和 B 类物品的个数,贡献就是一个组合数。而固定了 \(i\)\(k\),知道 A 类和 B 类物品的个数是容易的,可以 \(O(1)\) 求出。现在只要关心:对于所有可能的 \(j\),贡献系数的和是多少。发现将 \(a_i\) 从大到小排序后可能的 \(j\) 是一段后缀,因此只要知道了有多少个可能的 \(j\),贡献系数的和就是某个 \(2\) 的次幂减去 \(1\)。求多少个可能的 \(j\) 也是容易的,直接双指针一下即可。发现还有一种情况是后面全是 \(w=2\),没有选择任何一个 \(j\)。处理这种情况是容易的,此时贡献系数的和变成了某个 \(2\) 的次幂。总复杂度 \(O(n^2)\)

  2. P4695 [PA 2017] Banany

把式子拆成 \(a_t-(dep_s+dep_t-2\times dep_{lca(s,t)})\), \(dep_s\) 一项可以忽略。考虑先判掉 \(t\)\(s\) 子树内的情况,这是容易的。然后枚举 \(lca(s,t)\), 求出不和 \(s\) 在一个子树里的 \(a_t-dep_t\) 的最大值。类似 P11330 的套路,定义 \(g_s\) 为不考虑 \(s\) 的重儿子,\(a_t-dep_t+2\times dep_s\) 的最大值。查询的时候只需要考虑每个重链的底端即可。一共要动态维护每个点的 \(dep\),每个点的 \(a_x-dep_x\),以及 \(g_x\),总复杂度双 \(\log\)

  1. CF1119F Niyaz and Small Degrees

类似 P11038 的套路,考虑让所有点的度数 \(\lt i\) 的时候本来度数就满足条件的点是无用的,只用对度数 \(\ge i\) 的建出虚树。最简单的 dp 是 \(f_x\) 表示强制断掉 \(x\) 和父亲的边,满足条件的最小代价;\(g_x\) 表示强制连上和父亲的边。转移就先假装断了 \(x\) 的所有儿子,然后连上 \(ch-1/ch\) 个儿子,贪心地选 \(\Delta\) 最小的。于是在虚树上 dp 的时候对每个点维护对顶堆优化这个过程即可。

  1. CF1511G Chips on the board

\(cnt_i\)\(c_x=i\) 的个数。对于一组询问 \((l,r)\),显然 \(\oplus_{i=l}^{r} cnt_i\times (i-l)=0\) 的时候答案是 B, 否则答案是 A。先将所有 \(cnt_i:=cnt_i\bmod 2\)。接下来定义 \(f_{i,j}\) 为考虑 \([i,i+2^j-1]\) 中的数,\(\oplus_{k=i}^{i+2^j-1} (k-i)\times cnt_k\) 的值是多少。倍增的时候我们容易发现,只有最高位会受到影响,而这只和区间中有多少个非 0 的 \(cnt_i\) 有关。询问的时候我们同样发现,按从大往小的顺序倍增后,只有最高的几位会受到影响,和低位无关,可以快速计算贡献。总复杂度 \(O((m+q)\log n)\).

  1. TCO2011 Round 2 CircuitDesign

首先把两行中的孤点拿出来,最后再插回去,容易发现每个点都可以插在任意位置。然后发现每个连通块都可以独立考虑,最后乘上连通块数量的阶乘即可。现在我们只要对每个连通块单独求解。如果成环显然无解。否则显然是一棵树。一个很重要的结论:对于一个度数 \(\ge 2\) 的点,绝对不可能连 \(\gt 2\) 个度数 \(\ge 2\) 的点。这是显然的,如果这种情况出现显然会相交。因此我们发现,只考虑度数 \(\ge 2\) 的点,实际上形成了一条链!而每个点附近的度数为 \(1\) 的点可以随便排。最后再乘上这条链正过来和反过来两种情况即可。如果链是孤点,那么只有一种情况。

  1. P9357 Lighthouse

考虑第 \(i\) 次操作,\(v\)\(u\) 有贡献的情况数。发现只需要关心 \(u\)\(v\) 的路径上的点数。预处理出来每个长度对应多少条路径,只需要计算这个就行。如果枚举有贡献的那一次操作,那么不好优化。但是考虑另一种计数方法,枚举 \(m\) 次操作中有多少次操作在了路径上。那么依然能够很容易的计算出总方案数,并且用后缀和优化即可。

  1. P14637 [NOIP2025] 树的价值 / tree

首先有一个 \(n^3\) 的做法,设 \(dp_{i,j,k}\) 表示 \(i\) 子树里当前 \(\operatorname{mex}=j\)\(\gt j\) 的有 \(k\) 个(这也是延迟钦定的 trick)。考虑这个 dp 的转移,其实就是选择一个儿子把 \(\operatorname{mex}\) 继承过来,再用别的儿子的空位来增加这个 \(\operatorname{mex}\)。不妨把这个儿子叫做重儿子。那么对于一个填数方案,可以将它对应到一个剖分(类似重链剖分,由若干条链组成)。那么给定一个剖分,我们能算出它对应的最大答案吗?考虑一个数对它和它的祖先可能造成哪些贡献。发现如果它的祖先是由 \(a_1,a_2,\ldots,a_m\) 这些长度的链构成的话,会造成 \(\max(a_1,\ldots,a_m)\) 的贡献。具体的,显然不可能同时贡献到不同的链上;而对于长度最长的那条链,一定可以通过强制让它贡献到链底达成贡献的 \(\max\)。根据这个可以设计出 \(dp_{i,j,k}\) 表示 \(i\) 是链上第 \(j\) 个,历史最长链长度为 \(k\)\(i\) 的子树内最大的贡献和。转移是平凡的,复杂度 \(O(nm^2)\)。发现这个东西状态就是 \(O(nm^2)\) 的了,不行。设计 \(f_{i,j}\) 表示 \(i\) 是链顶,且历史最长长度为 \(j\)\(i\) 子树的最大价值;\(g_{i,j}\) 表示 \(i\) 是当前链底,当前链的长度和最长链的长度都是 \(j\), \(i\) 子树的最大价值。\(g_{i,j}\) 更好转移,直接看哪个儿子更适合延续这条链;\(f_{i,j}\) 则需要枚举和 \(i\) 距离是 \(j-1\) 的所有点作为当前链底,然后考虑路径上别的儿子作为链顶。直接写仍然是 \(O(nm^2)\) 的,但是注意到我们要做的就是单点加路径求和,用树状数组可以优化到 \(O(nm\log n)\)

  1. P14638 [NOIP2025] 序列询问 / query

考虑 \(2\times l\ge r\) 怎么做。把序列 \(l\) 个分一块,那么一个区间不会完整的包含两块。对于每一块一起求出答案。把包含这一块的某些点的区间分成三类:包含整块,左端点在块内和右端点在块内。三者都可以查询 ST 表快速更新,时间复杂度 \(O(n)\)。于是对于每个询问倍增分块就可以做到 \(O(nq\log n)\)。考虑优化,先预处理出来所有 \(l\)\(r\) 都是 \(2\) 的次幂的答案即可,总复杂度 \(O(nq+n\log^2 n)\)

  1. qoj1875 Nein

先将问题变为求第 \(n\)\(10^k-1\) 的倍数,使得它不包含任何 \(9\)。最后除以 \(10^k-1\) 即可。我们考察一个数是 \(10^k-1\) 的倍数有哪些性质。发现从个位开始,每 \(k\) 位分一段,总和也是 \(10^k-1\) 的倍数。而题目要求注定了这个数的位数不会很多,最保守的估计也不超过 \(20k\) 位。因此,这个总和实际上只有 \(20\) 种。我们考虑从头开始,逐位确定。考虑如何在确定了一个前缀后求出剩下有多少个数满足条件。首先统计出 \(0~k-1\) 每一位有多少个(\(cnt_i\)),再枚举最后的总和,然后做一遍数位 dp,记录一下进位即可。

  1. qoj2570 Maximal Subsequence

转化后就是选择出尽可能多的不交序列,都满足成为 LIS 的条件。考虑求出 \(dp_i\) 表示 \(i\) 结尾 lis 长度。然后对于 \(dp_i\) 相等的 \((j,a_j)\) 一定有 \(j\) 递增,\(a_j\) 递减。因此,每次贪心选下一个数即可,如果不行就删掉。

posted @ 2025-12-09 13:35  malin123  阅读(32)  评论(0)    收藏  举报