[北大校赛/题解] PKUCPC 2025 题解

题目链接

叠个甲 : 因为似乎没地方交题 , 所以只能口胡 , 可能 ( 必定 ) 出锅 .

不保证包括所有题目的完整解法


A.Angry Genshin Impact Player

原神玩家愤怒了 , 原神玩家看透了 OI 的本质 , 原神玩家出离愤怒了 .

其实就是在求有多大概率能够恰好达到 \(n\) .

设状态 \(f_i\) 表示能够在某一次转移后恰好到达 \(i\) 的概率 . 直接转移 : \(f_{i+n_j}\gets f_i\times p_j\) .

复杂度 \(O(nm)\) .

B.DataLab?

发现实际上能造成的有效操作情况并不多 , 可以讨论 .

先讨论 \(and\) 的影响 , 发现这个操作只在 \(d\subseteq p\) 时可以取 , 否则会使得 \(d\) 必然得不到 . 而且如果 \(d\subseteq p\) , 必然可以进行一次 \(and\ p\) , 使得结果不会更劣 .

这样就决定出了 \(and\) 操作是否进行 .

这时需要讨论的只有 \(or,xor\) 操作了 . 考虑 \(or\) 操作会把 \(p\) 对应位置全覆盖成 \(1\) , 因此一旦取 \(or\) , 只有两种情况 , \(or+xor\) 或者只有 \(or\) . 这种情况只有在 \(d\cap p\)\(1\) 或者全 \(0\) 时才可能取 .

否则 , 只能不取 \(or\) , 那么就分是否取 \(xor\) 两种情况 , 可以通过 \(a_1\) 来决定 .

通过以上讨论 , 已经确定了一组操作 , 使得如果有解, 这组操作必然有解 . 然后把这组操作在所有 \(a_i\) 上都试一遍就可以确定是否合法了 .

注意到可能存在没有进行任何操作的情况 , 这不符合题目要求 , 因此在操作开头加入两次 \(xor\) 相当于没操作 , 可以解决 .

根据讨论发现本质不同操作只有 \(8\) 种 , 因此也可以打表把他们找出来 .

C.Maximum Cut on a Number Line

通过打表等方式得出结论 : 选出值域上的一个区间作为选出的子集必然不劣 .

因此枚举左端点 , 动态加入右端点 , 可以 \(O(n^2)\) 解决 .

可以证明对于同一个右端点 \(r\) , 左端点 \(l\) 对应的值 \(f_l\) 是一个单峰函数 , 并且随着 \(r\) 的增加 , 同样的位置右移 \(l\) 一次的收益不减 , 因此这个函数的峰位置也不减 . 可以通过双指针 \(O(n)\) 解决 .

D.Triangular Tiling Taskforce

计算几何不会 .

E.Pool Management

发现这个流动过程与高度的 \(max\) 强相关 , 因此建出笛卡尔树 , 这个注水的过程相当于从笛卡尔树的叶子 , 不断跳父亲 , 并把父亲住满 , 同时在无法注满当前节点时 , 流向当前节点的另一个儿子 .

而排水的过程类似 , 用类似线段树的思路 , 从 \(l,r\) 的两条祖先链上排水即可 .

在数据随机的情况下 , 笛卡尔树的期望树高为 \(O(n\log n)\) , 因此可以暴力跳 .

在数据不随机的情况下 , 需要用数据结构维护树链上的信息 , 以快速实现上述两个操作 .

在良好的实现下可以做到 \(O(n\log n)\) .

F.A Magic Trick

结论是 , 逆序对数最多的情况一定是初始排列为倒序排列 .

因为对于任何一种操作方案 , 我们一定会使所有使用 \(L\) 操作的呈升序 , 所有使用 \(R\) 操作的呈升序 . 因此初始排列情况不会影响与 \(L,R\) 相关的逆序对 , 而且不操作的部分显然在倒序排列时最劣 .

因此我们针对倒序排列最小化逆序对数 . 首先只能 \(L\) 或者只能 \(R\) 的 , 一定会执行操作 , 因为这不会使任何一部分的逆序对变多 .

对于两种操作都能进行的 , 对于数字 \(i\) , 如果选 \(L\) , 贡献的逆序对个数为 \(<i\) 的 , 不操作或取 \(R\) 的个数 ; 如果选 \(R\) , 贡献的逆序对个数为 \(>i\) 的 , 不操作或取 \(L\) 的个数 .

发现如果 \(i<j\) , 且 \(i\)\(R\) , \(j\)\(L\) , 可以通过交换 \(i,j\) 使得逆序对个数变少 . 因此一定存在一个分界 \(k\) , 所有 \(i\le k\)\(L\) , 其余选 \(R\) .

从小到大移动指针 \(k\) , 动态维护指针 \(k\) 移动后对 \(k\) 这个数的取法改变 , 并且求出最小值 .

再加上其他几个部分的逆序对数即可 .

G.BUR

容易发现交换次数 \(STEP\) 就是排列 \(a_i\) 逆序对数 , 而轮数 \(REP\) 就是 \(\max(a_i-i)\) .

关于后半句的解释 : 容易发现 , 对于所有 \(a_i\le i\) , 即 \(a_i\) 向前移动的 , 可能在一轮中移动多次 . 但是对于 \(a_i>i\) 的 , 一轮中只能移动一次 , 并且直到到达其位置 , 每一轮都会移动 .

考虑计算出 \(f_i\) , 表示 \(REP=i\) 的所有排列的逆序对数之和 . 发现这个限制难以刻画 , 考虑容斥 .

\(g_i\) 表示 \(REP\le i\) 的所有排列的逆序对数之和 , 显然 \(f_i=g_i-g_{i-1}\) . 这个定义能够对应到构造排列时的限制 , 即数字 \(x\) 的位置只能在 \(\le x+i\) .

但是这个形式仍然不容易计算逆序对 , 考虑倒序插入 \(x\) , 维护的是已经插入的所有数在排列上的相对位置 , 若在较小的那个数处统计逆序对数 , 那么 \(x\) 统计的逆序对数就是它插入位置之前的个数 .

同时 , 上述限制可以等效转化为 \(x\) 插入位置之前的数字个数要 \(\le i\) . 容易证明在这种限制下构造出的排列不重不漏 . 这样第 \(j\) 次插入的数 ( 即 \(n-j+1\) ) 的方案数为 \(t=min(j,i+1)\) , 而它单独考虑时贡献的逆序对数为 \(\frac{t\times(t-1)}{2}\) .

因此有 :

\[\begin{aligned} g_i&=\sum \limits_{j=1}^{n}\frac{t_j\times(t_j-1)}{2} \sum \limits_{k=1}^{n}[k\ne j] t_k \\&=\sum \limits_{j=1}^{n}\frac{t_j-1}{2} \sum \limits_{k=1}^{n} t_k \\&=\sum \limits_{j=1}^{n}\frac{t_j-1}{2} \times (i+1)!\times (i+1)^{n-i-1} \\&= (i+1)!\times (i+1)^{n-i-1} \times \frac{1}{2}\left(\frac{i(i+1)}{2}+i(n-i-1 )\right) \end{aligned} \]

用快速幂 , 直接 \(O(n\log n)\) 计算即可 . 因为常数很小所以可以通过 . ( \(n\log n\) is all you need ) .

H.Quintuple

首先这个 \(5\) 长具有比较大的意义 , 因为在任意长度下似乎没有有效的多项式解 , 加上这个 "不相等" 形式的判断条件 , 可以从维护次大集合角度来做 .

具体地 , 我们枚举中间点 \(k\) , 找出所有与 \(k\) 颜色不同的 , 前驱二元组 \((i,j)\) 和后驱二元组 \((u,v)\) . 此时我们已经保证了 \(k\) 不会重复颜色 , 并且 \((i,j)\) , \((u,v)\) 二元组内部不重复 , 因此只需保证 \((i,j),(u,v)\) 两组之间不重即可 . 这个形式的问题下 , 显然对于确定的 \(k\) , 有效的二元组是很有限的 .

具体讨论下这个数量 . 首先对于确定的 \(j\) , 最多只有 \(4\)\(i\) 有效 . 对于 \((u,v)\) 对也是同理的 .

因此对于确定的 \(k\) , 枚举前驱的 \(j\) , 最多得到 \(O(n)\)\((i,j)\) 对 . 枚举后驱的 \(u\) , 最多得到 \(O(n)\)\((u,v)\) 对 . 但是此时仍不能暴力匹配 .

考虑这把 \((i,j)\) 对视为二位平面点 , 那么除了在 \(x=i,x=j,y=i,y=j\) 四条直线上的点 \((u,v)\) , 其余的都能用 \((i,j)\) 匹配 . 如果把这四条直线视作一个整体的点集 \(S\) , 那么多个点不能匹配的集合就是他们的 \(S\) 的交集 .

因此不断从大到小加入点 , 只有在加入后交集变小的情况下才加入 . 一开始有四条直线 , 每次交至少把一条直线变成两个点 , 或者消除一个点 . 因此至多有 13 个点 , 事实上这个上界几乎不可能达到 . 所以对 \((i,j)\) 维护好这个集合 , 再用所有的 \((u,v)\) 尝试匹配 , 即可得到 \(O(n^2)\) 的做法 .

I.Qualify

先处理令 \(d\) 排名最低的情况 . 首先于 \(d\) 相关的一定是以 \(-\infty\) 的净胜让 \(d\) 输 . 现在我们希望其他点尽可能满足比 \(d\) 排名大 , 称为过线 .

注意到对于任意点 \(i\) , 没确定的比赛至多两场 , 所以可以认为比赛关系构成链或环 .

考虑处理链 , 可以贪心 . 从链一端到另一端 , 假如当前点 \(x\) 可以通过赢后一个人来过线 , 让它过线一定不劣 , 因为最多只会使后一个人从过线变为不过线 . 如果能过线 , 让 \(x\) 尽可能以最小优势 ( 和后一个人的一场 , 优先输 , 其次平 , 并且最小化净胜球数 ) 过线 ; 否则让 \(x\) 对后一个人耻辱性的大败 ( 取 \(-\infty\) 净胜球数 ) .

考虑处理环 , 尝试断环为链 . 不妨在环上取一个点 \(x\) , 并且取出两侧相邻点 \(y,z\) . 通过枚举 \((x,y),(x,z)\) 两场的胜负 , 让环从 \(x\) 断开 , 然后沿用链的贪心 .

如果 \(x\) 在当前胜负下必不过线 , 那让这两场 \(x\) 的净胜都最小即可 .

如果 \(x\) 在当前胜负下必能过线 ( 即胜场数过线 ) , 那么仍然在可能范围内最小化 \(x\) 的净胜 .

问题在于如果 \(x\) 胜场数恰好和 \(d\) 相同 , 他的过线由净胜数决定 . 不过线的情况仍然最小化 , 但是过线的情况需要单独讨论 .

可以发现 , 对于 \((x,y)\) 的净胜量 \(g_y\) 的调整最多只会导致链上的答案发生 \(1\) 的变化 , 考虑让 \(g_y\) 初始取对 \(y\) 最有利的值 , 也钦定 \(g_z\) 取对 \(z\) 最有利的值 . 这样不断把 \(g_y\) 变劣直到答案减少 , 这时的取法一定是不优的 , 因此 \(g_y\) 取答案仍然较优的最小值 . 二分出这个 \(g_y\) , 再用这个 \(g_y\) 对应的 \(g_z\) 算出正确的答案 .

在这种情况下保证了 \(z\) 之外的没有因为 \(g_y\) 变小而变劣 , 同时尽可能最优了 \(z\) , 因此这个策略没有问题 .

J.Optimal Flight Route

看起来仍然是个最短路状物 , 不过仔细研究会发现 , 真正决定答案的是一条航线在 \(s\) 出发的情况下是否能赶上 , 以及在 \(s\) 的出发时间 .

因此我们实际上只需对于每条航线算出它最大的在 \(s\) 出发的时间 ( 不能到达视为 \(-\inf\) ) . 按照出发时间枚举航线 , 它的最大出发时间就是所有能在航线出发时间前 \(3\) 小时到达出发点的 , 所有航班的最大出发时间 . 用堆维护所有已经考虑过的航线的到达时间 , 一旦合法 , 就更新它的到达点的最大出发时间 . 特别地 , 从 \(s\) 出发的航线的最大出发时间就是这条航线的时间本身 .

复杂度 \(O(n\log n)\) .

K.Zuma

为了方便 , 把连续同色缩成一段 , 用 \(num_i\) 表示第 \(i\) 段的个数 .

考虑区间 dp , 令 \(f_{l,r}\) 表示把 \([l,r]\) 区间全消除的最小花费 .

考虑讨论左端点的消去方式进行转移 .

最简单的就是直接消除左端点 , 用 \(f_{l+1,r}+(3-num_l)\) 来转移 .

考虑左端点通过与右边的同色点拼合来消去 .

考虑拼合的几段的个数只可能有以下几种情况 : \((1,1),(1,2),(2,1),(2,2),(1,1,1),(1,1,2),(2,1,1),(1,1,1,1)\) , 其他情况下可以证明不可能拼成一段消掉 .

两两拼合的可以通过枚举拼合的点来更新 .

考虑右端与两个 \(1\) 的拼合情况 : \((1,1,1),(2,1,1)\) , 发现相当于在右边拼合了一个由两个 \(1\) 构成的 \(2\) , 因此再维护一个 \(g_{l,r}\) 表示用 \(l\) 和区间内的另一个点拼出一个 \(2\) 的最小花费 , 然后枚举拼合的 \(g\) 的位置 .

现在只剩下 \((1,1,2)\)\((1,1,1,1)\) 两种情况了 , 发现这相当于右端拼合了一个 : 一个 \(1\) 和一个 \(2\) ( 可能是通过两个 \(1\) 拼出的 \(2\) ) 的整体 , 用 \(t_{l,r}\) 表示用 \(l\) 和区间内的点拼出一个这样的结构的最小花费 , 用 \(g\) 去更新 \(t\) , 然后类似地更新 \(f\) 即可 .

复杂度 \(O(n^3)\) .

L.Game on Tree

先从简单情况入手 , 讨论链 , 发现这是简单的 , 即点数 \(\equiv1\pmod 3\) 的情况下必败 , 否则必胜 .

考虑在链的基础上加分支 , 发现如果有叶子连在度数 \(>2\) 的点上 , 那么先手必胜 .

这是因为考虑去掉这个叶子之后的图 \(G'\) , 如果图 \(G'\) 先手必败 , 那么先手只需取掉这个叶子把 \(G'\) 给对手 . 如果 \(G'\) 先手必胜 , 因为去掉这个叶子后 , 它连的点度数仍然 \(\ge 2\) 不可能是叶子 , 因此 \(G'\) 的先手必胜策略取的点不会包含这个叶子连的点 , 因此可以同时去掉这个叶子和 \(G'\) 先手必胜策略 .

称度数 \(>2\) 的点为结点 , 每个叶子到最近结点的距离为 \(len\) , 那么现在的博弈变成了有 \(len=1\) 的叶子就赢 . 因此 , 如果有 \(len=2\) 的叶子 , 一定不会取它 , 否则一定会给对方 \(len=1\) 的叶子 .

以此类推 , 如果一方有 \(len=3\) , 一定可以取 , 把不好的 \(len=2\) 留给对方 . 进一步的结论是 , 只要存在奇数 \(len\) 就必胜 , 否则必败 .

严谨的证明是 , 只要存在奇数 \(len\) , 一定可以把所有奇数 \(len\) 都取成偶数 , 而对方面对全偶数 \(len\) 总会取成存在奇数 \(len\) . 根据归纳法得证 .

对链需要单独特判 , 其余的只需找一个结点作为根 dfs 一边就能求出 \(len\) , 复杂度 \(O(n)\) .

M.Mysterious sequence

签到题 . 因为可以随意重排 , 我们只关心 \(0\) , \(1\) 的数量是否合法 . 通过二元一次方程可以解出如果当前串和模式串 \(0\) , \(1\) 数量不对应 , 翻转的 \(k\) 个里 \(0\) , \(1\) 分别有多少 , 然后判定是否能做到即可 .

posted @ 2025-06-21 16:38  youlv  阅读(66)  评论(0)    收藏  举报