LNOI2022 游记(T3 官方题解 added)
这套出的比较匆忙,五月十五号得到的二十五号恢复省选的消息,当天就找人拉了些题目,十六号跟大家讨论了一下大家认为 adhoc 太多了于是捏了个现在的 T2 丢掉了一个别的题。一个是大部分出题人都比较忙或者比较鸽,另一个是大部分验题人(除了粉兔)都比较忙或者比较鸽,还有一个是因为个人情感原因阻体仁的效率也不太高,尽管帮其他题目做了主要的验题、验样例、改题面的工作,修掉了很多的问题,最终我的题还是出了点小锅锅,感觉我真的有点失败。
T1 的难度我也不太说得清楚,定位是小清新贪心,或许比 T2 简单?但好像最终的结果是大家随便写一点乱七八糟东西就 85/90 了,成功变成摇奖题,场上两个 100 的代码也不太懂在干什么(?)。对此某位我也不知道愿不愿意透露姓名的出题人是这样认为的(可能并不)。
我的评价是,多组数据好文明,以后还是记得整点多组数据。
T2 的定位是跟 CSP 和 NOIP 对应位置类似的 DP 题,大力转移,然后需要做一点状态数的分析。第三组数据解释 \(T=213\) 写成 \(T=231\) 产生了一些影响(在洛谷题面里面改掉了),真诚地给受影响的选手道歉。不过五点(考试五点半结束)才接到关于这个的提问我也觉得挺奇怪,其他人都不看样例解释吗?另外这题只有 3 个 100 + 1 个 90,也不是特别符合我对这道题的得分分布期待。或许大家都不会 DP(?)
T3 和 T4 的难度可能没有想象中把控得那么好(预计 T3 是对标 AHOI T2 的),原本以为大概就是 40+40,但最后 zwz 过了 T3 我还是有点小小惊讶的。
T3 原本定位也是一个比较清新的推狮子,出题人给的做法似乎比较正常但我的硬推做法推了四页纸然后对着样例拟合了好一会儿系数,所以我觉得还是有点不太健康。
T4 没有人通过在我意料之中(因为我也不会),不过感觉这种题目看起来挺善良其实跟一般 OI 的题目风格还是有点格格不入(在看完题解之后大家大概会理解我为啥这么想),感觉不太符合正常 OI 选手的脑回路,应该丢 CF 上。同时感觉数据不是很强,欢迎大家乱搞试试,不过场上只有写 dp 的,有点遗憾。
总的来说尽管基本完好地搞定了整场省选的工作,但这次的题目和最终呈现出来的比赛样貌相比 AHOI 更加没有达到我的理想状态,一个是时间原因和题源原因,另一个确实是大家在期末前都更忙一点以及个人状态不佳吧。不过尽管如此还是感谢所有出题人和验题人为比赛顺利进行付出的努力。
底下放个毛姑姑题解
吃(food)
观察 1:一定是先加再乘(显然)
观察 2:\(a_i = 1\) 的一定会选加(显然),先把它们加到 \(X\) 上去
观察 3:在 \(a_i \geq 2\) 的前提下,至多选择加 \(b_i\) 一次(若加了多次,只保留 \(b_i\) 最大的那个加,其他都乘,容易发现一定不劣)
于是在全部乘的前提下,将乘 \(a_i\) 变成加 \(b_i\) 会让答案的比例乘上 \(\frac{b_i+X}{a_iX}\)。取这个比例的最大值即可找到方案。
题(problem)
大力 DP 就完事了。先不考虑 \(\{a_{i,1},a_{i,2},a_{i,3}\}\) 的顺序,最后乘上 \(n!\) 即可。
设 \(f_{i,j,k,l,p,q,r}\) 表示考虑了序列的前 \(i\) 个元素,\(j,k,l\) 分别代表子序列 \(\{a_{s,1},a_{s,2},a_{s,3}\}\) 的数量,满足 \(a_{s,1} \leq i, a_{s,2} \geq i\),且 \(t_{a_{s,1}} = 1,2,3\)。\(p,q,r\) 分别代表子序列 \(\{a_{s,1},a_{s,2},a_{s,3}\}\) 的数量,满足 \(a_{s,2} \leq i, a_{s,3} \geq i,\) 且 \(\{t_{a_{s,1}},t_{a_{s,2}}\} = \{1,3\}, \{3,2\}, \{2,1\}\)。转移根据 \(1,2,3\) 分别填在哪个序列后面决定。复杂度 \(O(n^7)\),看起来不太能通过。
注意到状态需要满足 \(j+k+l+p+q+r \leq n\) 才有意义,只保留这些状态,后六维的状态数是 \(\binom{n+5}{6}\) 的,有一个 \(\frac{1}{6!}\) 的常数,可以较为容易地通过。当然还可以更精细分析跑得更快。开 \(20^6\) 的数组需要滚动卡一下空间。
盒(box)By Itst
将答案对每条边拆开,设
则答案为 \(\sum_{i=1}^{n-1} w_i f_{N,S,i,\sum_{j=1}^i a_j}\)。注意到 \(N,S\) 都不大,而且在 \(i\) 增大的时候 \(K,A\) 两维都是增大的,所以如果可以 \(O(1)\) 支持将当前的 \(f\) 的下标对 \(K\) 或对 \(A\) 加一动态维护答案就解决了这个题。
先考虑对 \(A\) 差分。下面的符号 \(\frac{\Delta f_{N,K,S,A}}{\Delta A}\) 表示的是 \(f_{N,K,S,A+1}-f_{N,K,S,A}\),下面带 \(\Delta K\) 的也是类似。
而 \(\frac{\Delta g_{N,K,S,A}}{\Delta A}\) 是简单的。对 \(K\) 的差分比较复杂,下面假设 \(K \geq 1\),否则杨辉三角需要一些 corner 的额外定义。先考虑 \(g_{N,K,S,A}\) 的差分。
其边界(\(A=0\))是容易计算的,而后面的和式注意到递归的过程中 \(S-A\) 不变,而前面的和式形如 \(\sum_{i=0}^A \binom{K-1+i}{K-1} = \binom{K+A}{K}\),最后可以得到
类似推 \(f\):
又是一个递归的模式,将递归出的系数加起来,可以得到。
再用上面的同一套方法维护一个 \(g_{N+1,S-1,K+1,A-1}\)(其实只有一个组合数的下标改变了)即可。
盒(box)By zjc
算法三
设 \(s_i = \sum_{j = 1}^{i} a_j\) ,那么我们关注的量为 \(\sum_{j = 0}^{S} \lvert j - s_i \rvert {i - 1 + j \choose j} \cdot {n - i - 1 + m - j \choose m - j}\)
考虑:$$\sum_{j = 0}^{S} \lvert j - s_i \rvert {i - 1 + j \choose j} \cdot {n - i - 1 + S - j \choose S - j} \ = \sum_{j = 0}^{S} (j - s_i) {i - 1 + j \choose j} \cdot {n - i - 1 + S - j \choose S - j} + 2\sum_{j = 0}^{s_i - 1} (s_i - j) {i - 1 + j \choose j} \cdot {n - i - 1 + S - j \choose S - j} $$
我们用 \(j {i - 1 + j \choose j} = i {i - 1 + j \choose j - 1}\) 来做变型,则等式的前一项变为:$$ i \sum_{j = 0}^{S - 1} {i + j \choose j} \cdot {n - i + S - 1 - j \choose S - 1 - j} - s_i \sum_{j = 0}^{S} {i - 1 + j \choose j} \cdot {n - i - 1 + S - j \choose S - j}$$
而第二个和式可以理解为从 \((0, 0)\) 走到 \((n - 1, S)\),每一步只能向上或者向右走的走法数量。第一个和式可以理解为从 \((0, 0)\) 走到 \((n, S - 1)\) 的走法数量。
等式中后一项也可以做同样的变换,可以变为:
\(2(s_i \sum_{j = 0}^{s_i - 1} {i - 1 + j \choose j} \cdot {n - i - 1 + S - j \choose S - j} - i \sum_{j = 0}^{s_i - 2} {i + j \choose j} \cdot {n - i + S - 1 - j \choose S - 1 - j})\)
考虑上式的组合意义,我们发现只需回答 \(2n\) 个如下问题的答案:
从 \((0, 0)\) 走到 \((N, M)\), 每一步只能向上走或向右走,且从 \((P, j)\) 走到 \((P + 1, j)\) 的那一步必须满足 \(j < Q\),走法数量有多少个。(\(N, M\) 的记号与前面的没有关系)
如果我们是枚举 \(j\),那么复杂度仍然与算法二相同。但这条路径需要满足的条件等价于:每一步只能向上走或向右走,且从 \((k, Q - 1)\) 走到 \((k, Q)\) 的那一步必须满足 \(k > P\)。因此可以用 \(O(n)\) 个组合数计算出如下问题的答案。
时间复杂度 \(O(n^2 + S)\),可以获得 \(50\) 分。
算法四
对于特殊性质 B,选手只需推出 \(s_i = 0\) 的时候的组合数表达式,并对后面 \(20\) 个 \(s_i \neq 0\) 的情形暴力计算即可。
算法五
对于特殊性质 AC,我们不难发现可以把最终答案拆成 \(20 \cdot 2\) 个如下问题:
考虑一个从 \((0, 0)\) 走到 \((N, M)\) 的路径,每一步只能向上或向右走。且一条路径的贡献是路径上所有 \((i, j)\) 到 \((i + 1, j)\) 的边,其中需要满足 \(L \leq i \leq R, j \leq Q\)。
通过前缀和的转换,不妨设 \(L = 0\)。我们枚举这条路径是从哪个点穿出由 \((0, 0), (R, 0), (0, Q), (R, Q)\) 构成的矩形的,即可在 \(O(N + M)\) 的时间内完成计算。
算法六
注意到算法三的问题,可以在 \(O(1)\) 时间内从 \((N, M, P, Q)\) 的答案得到 \((N, M, P, Q + 1)\) 的答案,也可以在 \(O(1)\) 时间内从 \((N, M, P, Q)\) 的答案得到 \((N, M, P + 1, Q)\) 的答案(只需做算法三所提到的转换即可)。又注意到我们需要回答的 \((N, M, P, Q)\) 的全体满足:\(N = n - 1, M = S\),且 \(Q\) 关于 \(P\) 单调变化,或 \(N = n, M = S - 1\),且 \(Q\) 关于 \(P\) 单调变化。因此,固定 \(N, M\),按 \(P\) 从小到大,\(Q\) 从小到大的顺序依次来回答询问,每次从上一次的答案转移到这一次的答案,就可以做到 \(O(n + S)\) 的复杂度了。期望得分 \(100\) 分。
串(string)
观察 1:一定存在一个最优的序列 \(T_0 = \epsilon\)(样例解释提示了这一点),否则你总可以找到一个新的同样长的序列,使得新的序列的每一个字符串是原序列对应位置字符串的后缀。
观察 2:称一个子串 \(S'\) 可以被生成当且仅当存在一个字符串序列满足 \(T_0 = \epsilon, T_{|S'|} = S'\)。则若一个串在 \(S\) 中出现了大于等于 \(2\) 次,其一定可以被生成。证明此观察考虑倒过来思考该过程:若其两次出现分别在 \([i_1,j_1]\) 和 \([i_2,j_2]\),则从 \([i_2,j_2]\) 开始,每次将 \([i,j]\) 换成 \([i-1,j-2]\) 得到当前串在字符串序列中的前驱。当左端点顶到 \(i_1\) 的时候,因为 \([i_1,j_1]\) 和 \([i_2,j_2]\) 一样,所以可以将这个区间送到 \(i_2\) 开始然后继续做直到删空。
观察 3:某个子串可以被生成当且仅当其出现次数 \(\geq 2\),或者设其在 \(S\) 中唯一一次出现为 \([i,j]\),则不断做 \([i,j] \to [i-1,j-2]\),在左端点小于等于 \(0\) 前可以到达空串或者出现次数 \(\geq 2\) 的串。这容易从观察 2 推出。
因此设 \(f_x\) 表示右端点为 \(x\)、出现次数大于等于 \(2\) 的最长串长度,则答案是 \(\max(\frac{|S|}{2}, \max_{1 \leq i \leq |S|} f_i + \lfloor \frac{|S| - i}{2} \rfloor)\)。求 \(f_i\) 只需要对 \(S\) reverse 后求出 SA 的 height 数组即可。