MOCK NOIP 20221015 日志

恕我语文不好,实在不晓得用何种词汇来描述看到下文的感受:

此比赛为正常的提高组难度,甚至可以用来作为普及组模拟赛。 请选手 AK 后不要大声喧哗,以免影响他人 AK。

尤其是这套题的出题人是张隽铠的情况下。当然,OI 圈风气本就如此,我也不好过多评价。No comment.

T1 还算顺利,半小时左右搞定。T2 是大分类讨论,足够恶心人,但好在有相当可观的可以通过暴力与观察拿到的部分分。T3 猜测与线性基相关,但没有相应知识储备,暴力跑路。

T4 就……反正出题人开心就好。到现在都没人改出来。

一句话题解

A – 序列

依次往某个子序列中添加元素。则添加的元素必然成为新的最大值/最小值之一,否则违背题意。

于是枚举子序列首元素,将以其开头的严格上升子序列数与严格下降子序列数相乘即可。使用树状数组转移即可。复杂度 O(nlogn)\operatorname{O}(n \log n)

B – 最段路

85 pts\text{85 pts} 做法

依次枚举起点为 (0,0)0,,(0,0)3(0,0)0,\cdots,(0,0)3 暴力 BFS,可以通过 a,b2000a,b\leq 2000a2b2a \leq 2\lor b\leq 2 的数据,需作常数优化(评测时也别开多线程)。

打表观察 a=ba=b 时答案的性质,可以获得另外一部分分数。

正解

我们还是考虑在网格图上移动。不过代价分 33 种:

  • 在相邻的两个网格点之间移动,权值为 11
  • 在某个网格点旋转 90,9090^\circ, -90^\circ,权值为 11
  • 按当前方向通过网格点,权值为 22

自然地,我们尽可能利用前两种边到达终点,尽可能不直接通过网格点。例如,当 a<ba<b 时,我们最多可以造成 2a2a 次转向。

实际情况可以分为:

  • (0,0)0(0,0)0 出发,抵达 (a,b)3(a,b)3(右侧出发上方到达);
  • (0,0)0(0,0)0 出发,抵达 (a,b)2(a,b)2(右侧出发左侧到达);
  • (0,0)1(0,0)1 出发,抵达 (a,b)3(a,b)3(下方出发上方到达);
  • (0,0)1(0,0)1 出发,抵达 (a,b)2(a,b)2(下方出发左侧到达)。

上述四种可以化归为两种,分别计算钦定出发/到达方向后的最段路长度和路径数。但仍需分别考虑 a<b,a=b,a>ba<b,a=b,a>b,以及 a,b2a,b\leq 2 时的特殊情况,非常繁琐。

C – 集合

线性空间 – OI-Wiki
高斯消元 – OI-Wiki

对矩阵进行初等行变换,行空间(所有行向量张成的线性空间)不改变。列亦然。

Hamel 基 – OI-Wiki

nnmm 维向量排成 n×mn\times m 的矩阵,作高斯消元消成上三角矩阵,表出的线性空间不变,所有非 θ\theta0\mathbf{0} 元)向量构成该线性空间的一个 Hamel 基。

不论开始初等行变换时选择哪些元素作为主元,对于一组确定的向量,其张成的线性空间仍保持不变。()(*)

正因如此,在异或线性空间中, nn 个二进制数(均为长为 mm 的 01 向量)相互异或能表示出的所有数(张成的线性空间),可以在 O(nm)\operatorname{O}(nm) 的时间内求出其线性基(作行初等变换)。我们依次考虑向量的第 i=1,,mi=1,\cdots,m 维(二进制表示下的第 m1,,0m-1,\cdots,0 位),选择一个该维非 00 的向量作为主元,消去其他所有向量的这一维,最终会得到一个每一维至多只有 11 个行向量不为 00 的线性基(二进制最高位互不相同)。

那么,通过贪心/二进制拆分等技巧,可以在 O(m)\operatorname{O}(m) 的时间内求出该线性空间的最大/第 kk 大元素、查询某向量能否被该基表出,同时借此支持元素的动态插入/删除。

正解

考虑一个方案的最终权值为 (bi)(ci)(\sum b_i)(\sum c_i)。我们将其视作平面直角坐标系中一点 (bi,ci)(\sum b_i,\sum c_i),则所有方案构成的点集中,显然只有下凸壳上的点可能成为最优解。

解一 – 迭代求取实际凸壳

洛谷题库 P5540 最小乘积生成树 和该解法关联密切。通过贪心,找到最接近 x,yx, y 轴的两个点 A,BA, B,是为只考虑 bi\sum b_ici\sum c_i 最小化时的方案。我们找一点 CC,使得他与 A,BA, B 能构成下凸壳,且 SABCS_{\triangle ABC} 最大(CCABAB 的距离最大)。考虑 SABC=12ACBCS_{\triangle ABC}=\frac{1}{2}\overrightarrow{AC}\cdot\overrightarrow{BC},有只与 xA,xB,yA,yBx_A,x_B,y_A,y_B 的线性相关项,可以将二维权值转化为一维,排序后贪心求解即可求出 CC。分别对 B,CB,CA,CA,C 作上述迭代即可。

至于复杂度……李天游说决策点实际上有 2n2^n (还是 n!n!?)个,在 nn\sim \infty 时由 nn 个点构成的点集的凸壳上点数期望是 O(lnn)\operatorname{O}(\ln \sqrt{n}) 级别的。实际上该解法跑得很快(因为难以构造高强度数据)。

解二 – 利用必要非充分条件——反比例函数切线截矩

如图。显然 AA 最优,但 AA 亦在 BB 构造的反比例函数切线上方。

(bi,ci)(\sum b_i,\sum c_i) 成为最优解,则考虑经过它的直线 y=kx+by=-kx+b,其中 k=cibik=\frac{\sum c_i}{\sum b_i},是为反比例函数 xy=(bi,ci)xy=(\sum b_i,\sum c_i)x=bix=\sum b_i 处的导数之相反数;b=2cib=2\sum c_i。则显然地,所有其他决策点都应在该直线上方。换句话说,过每个点作斜率为 k-k 的直线,最优解所在点的截矩 bb 最小;反之则不一定成立。这是该点成为最优解的必要非充分条件。

考虑一个固定的 kk。对于一点 (bi,ci)(\sum b_i,\sum c_i),其截矩为 ci+kbi\sum c_i+k\sum b_i;同时,若权值是一维且具有偏序关系,很容易排序后贪心求取一组向量的权值最大/最小线性基。所以我们直接考虑每个元素的一维权值为 ci+kbic_i+kb_i,排序后依次尝试加入线性基,(对于所有可能的 kk)最终得到的答案将一定包含最优解。

若把 kk 看作自变量,bi,cib_i, c_i 分别作斜率和截矩,则 nn 条一次函数的交点是 O(n2)\operatorname{O}(n^2) 级别的。所以我们求出使得相对大小改变的所有 kk,从小到大依次考虑决策集合,就会有“互换两个序列中相邻元素后重新贪心求取整个序列的线性基”的需求。我们不必遍历整个序列——由 ()(*) 可知,序列前缀张成的线性空间不变,故尝试取出并重新将这两个元素加入线性基是正确的。

时间复杂度 O(n2logn)\operatorname{O}(n^2 \log n)

D – 字符串

待补。

  • 2022年10月19日