2026.8.12 模拟赛
https://oj.gxyzh.com/d/hzoj/contest/6a4600744de4613bd328ca15
这场打得是不太好,只有 30 分,暴力分不会打,应当反思.
| T1 | T2 | T3 | T4 | |
|---|---|---|---|---|
| 实际得分 | 20 | 10 | 0 | 0 |
| 期望得分 | 20 | 10 | 0 | 10 |
| 能力得分 | 100 | 25~100 | 20 | 40 |
第负一题
求区间最大带权独立集的总和.
由于是独立集问题,考虑 DP;由于总共有 \(O(n^2)\) 个区间,因此考虑使用分治优化(猫树分治).
对于所有区间,将其拆成在 \(mid\) 左右两侧两部分.
记 \(g_{i,0/1}\) 表示左右区间中,第 \(i\) 位,钦定取/不取边界点的最大贡献,使用 DP 辅助是已于求出的.
那么区间 \([L,R]\) 的贡献为 \(\max\{g_{L,0}+\max(g_{R,0},g_{R,1}),g_{L,1}+g_{R,0}\}\).
考虑固定左端点,统计右端点的贡献:
当 \(g_{L,0}+\max(g_{R,0},g_{R,1})\ge g_{L,1}+g_{R,0}\) 时选取第一种贡献.
移项可得:\(\max(g_{R,0},g_{R,1})-g_{R,0}\ge g_{L,1}-g_{L,0}\).
将左侧的排序,二分出边界,使用前缀和统计.
时间复杂度为 \(O(n\log ^2n)\).
数树
场上不会写 35 分的状压.
对于这道题,由于存在边的约束条件,而这种条件不好处理,故考虑容斥.
由于 \(a_v=a_u+1\) 时是不合法的边,因此不合法的边构成若干条链.
设 \(F_i\) 表示有 \(i\) 条边不合法,\(G_i\) 表示钦定 \(i\) 条边不合法的方案数.
\(F_i\) 与 \(G_i\) 之间可以通过容斥转化,现在考虑求 \(G_i\).
考虑如果我们知道了有 \(j\) 条边是不合法的,那么树会被划分成 \(n-j\) 条链,那么染色方式只有 \((n-j)!\) 种,现在我们要求钦定 \(j\) 条边不合法的方案数.
这是可以使用 DP 解决的,设 \(dp_{i,j,0/1/2/3}\) 表示对于节点 \(i\),子树内有 \(j\) 条边不合法,以及节点 \(i\) 的状态:
- 子树内没有相邻的边;
- 子树内相邻的边只有一条出边;
- 子树内相邻的边只有一条入边;
- 子树内相邻的边只有一条出边,一条入边;
使用树上背包,时间复杂度为 \(O(n^2)\).
石子游戏
这是多堆 Bachet 游戏,因此可以使用 \(SG\) 函数:
若异或和为 \(0\),则后手赢,否则先手赢.
即我们需要求:
将 \(\bmod\) 拆开:
由于有 \(\frac{a_i}{k}\),故考虑枚举这一维,则时间复杂度为 \(O(n\log n)\),
即 \(\left \lfloor \frac{a_i}{k} \right \rfloor=r\),枚举 \(a_i\in [rk,(r+1)k)\).
可以先对值域做一个异或 \(c_i\),之后考虑统计:
考虑按位统计,设 \(f_{i,j}\) 表示:第 \(j\) 位的 \(\oplus (k-i)[c_k]\) 的值.
记 \(o(L,R)\) 表示区间 \([L,R]\) 中数的个数的奇偶性.
则有如下转移:
考虑统计对于区间 \([L,R]\) 的答案:
记 $z=\left \lfloor \frac{R-L}{2^{j+1}} \right \rfloor $
时间复杂度 \(O(n\log n\log n)\),可以进行剪枝.
子段和
这道题是比较好的,当然也是比较史的.
首先考虑对于每一个 \(K\) 统计 \(g(K)\):
将 \(a_i\) 序列进行前缀和,那么每次操作就是后缀减,最大子段和就是:\(\max_{i<j}(a_j-a_i)\).
考虑二分答案,设 check 的最大子段和为 \(w\):
可以使用如下方法进行 check,需要满足 \(\forall i<j,a_j-a_i\le w\):
从前向后贪心,维护 \(lim\) 表示后缀的最大值,\(cnt\) 表示操作次数:
- 若 \(a_i>lim\),则将 \(a_i\) 及后缀减去 \(a_i-lim\).
- 令 \(lim=\min(lim,a_i+w)\)
事实上我们不需要每次将后缀操作,只需要令 \(lim=a_i\) 即可.
时间复杂度为 \(O(Kn\log w)\).
考虑优化:
记上面的 check 时的函数为 \(c(w)\),表示将最大子段和变成 \(w\) 的最小操作次数.
由于惊人的注意力:发现 \(c(w)\) 是单减的,并且斜率也是单减的,并且斜率不超过 \(n\).
因此可以处理出每一种斜率的位置,时间复杂度为 \(O(n^2\log w)\).
继续考虑优化:
现在复杂度的瓶颈在于求 \(c(w)\) 单次是 \(O(n)\),需要优化.
考虑将所有 \(c(w)\) 放在一起统一求出:
记 \(lim(w)\) 与 \(cnt(w)\).
- 初始时,\(lim(w)=w\),构成斜率为 \(1\) 的线段.
- 对所有 \(lim(w)<a_i\) 统计答案,并统一修改为 \(a_i\),构成斜率为 \(0\) 的线段.
- 对于所有 \(a_i+w<lim(w)\) 的 \(lim(w)\) 统一修改为 \(a_i+w\),是斜率为 \(1\) 的线段.
综上,\(lim(w)\) 总是构成若干条斜率为 \(0/1\) 的线段.
并且每次修改均是修改前缀的 \(lim(w)\),替换成一条新的线段.
这个过程可以使用单调栈维护,使用线段树统计 \(cnt(w)\).
之后查询 \(c(w)\) 时,在线段树上查询即可,单次复杂度为 \(O(\log w)\).
综上,总时间复杂度为 \(O(n\log^2 w)\),卡卡就过了.

浙公网安备 33010602011771号