Atcoder ABC422 题解
ABC422
好久没写题解了。省流:VP,90min AK。一雪前耻。
A
设关卡为 \((n,m)\),考虑 \(m \gets m+1\)。如果 \(m=9\) 就令 \(m \gets 1,n \gets n+1\)。简单的判断。
B
对于每个 #
方格枚举周围四格,数一下个数,也没什么好说的。
C
不想判断 corner。极度不动脑子。就是二分一个 \(x\),合法条件就是,\(x\) 要小于 A
的个数且小于 C
的个数,且剩余字符数量大于等于 \(x\)。
D
直观的感受是,平均分配。考虑这么构造:
设 \(q = \left \lfloor \frac k {2^n} \right \rfloor,r=k-q \times 2^n\)。给数组中每个元素赋上初值 \(q\),再考虑进行 \(r\) 次 \(+1\) 操作。
然后对左半和右半平均分配 \(r\) 次 \(+1\) 操作。递归地处理。
算最终的 \(X\) 的话,就可以直接倒着再算一遍,复杂度是可以接受的。
写代码 naive 了。由这个构造方式不难发现,当 $r >0 $ 时最终的 \(X\) 一定等于 \(1\)。而此时必存在一组 \((a_i,a_j)\) 满足 \(a_i \ne a_j\),故 \(X\) 的一个下界是 \(1\)。这也侧面印证了我们构造的正确性。
E
考虑一件事情,要同时满足多余一半的点共线。这个好像一看就很能乱搞。
每一轮随机一个点对 \((A,B)\),求出其所在直线,然后判断是否有大于一半的点在这条直线上。
\(200\) 轮之后,如果还没有找出来,就输出 No
。
看看这个算法不对的概率。每一次这两个点中有一个点不在那【穿过 \(> \frac n 2\) 个点的】直线上的概率是 \(0.75\) 左右。然后随机 \(200\) 轮错误的概率是 \(0.75^200 \approx 10^{-25}\)。错掉的概率比【下一秒被飞机创四的概率(——dXqwq)】还小。
F
(我认为)普通的 Dijkstra 显然是不能完成这个问题的。原因在于,边权是随更新到的自身重量变化而变化的,无法维护。
然后考虑拆开每种路径的贡献。对于一条路径 \(u_{k-1} \to u_{k-2} \to \dots \to u_0\),发现答案实际上是 \(\sum_{i=0}^{k-1} i \times v_{u_i}\)。也就是,每个点的贡献可以理解为,和到当前点的路径长度有关。
这时候你发现 \(m \le 5000\)。考虑类似 Bellman-Ford 的手法。
设一个 DP 状态 \(f_{u, i}\) 表示到 \(u\),路径长度为 \(i\) 的贡献。
这里因为是反向更新的(可以理解一下),所以初始状态是 \(\forall i\),有 \(f_{1, i}=0\),其余为 \(+\infty\)。
然后转移式子也非常平凡。\(f_{u, i} \gets \min_{v \in G_u}\{f_{v, i+1} + i \times v_u\}\),这里 \(G_u\) 指 \(u\) 的邻居。
答案就是 \(f_{i,0}\)。
G
怎么说呢。是不是全场最简单的题了。
设第 \(1,2,3\) 个盒子里面分别有 \(AX,BY,CZ\) 个球。限制就是,\(AX+BY+CZ=N\)。
Problem 1
球无标号,就是求不定方程解的个数。设生成函数
然后答案显然就是 \([x^N](F1 * F2 * F3)\)。
Problem 2
球有标号,每一组 \((X,Y,Z)\) 带来的贡献就是广义组合数 \(\frac{N!}{(AX)!(BY)!(CZ)!}\),所以设指数型生成函数
然后答案显然就是 \(N! \times [x^N](F1 * F2 * F3)\)。