AtCoder Beginner Contest 247
A - Move Right
输入输出。
B - Unique Nicknames
循环。
C - 1 2 1 3 1 2 1
简单模拟。
D - Cylinder
注意到是一个队列的结构,然后直接模拟就可以了。
入队最多\(n\)次,所以出队也最多\(n\)次,直接模拟复杂度为线性。
E - Max Min
对于\(x = y\)的情况,只有全为\(x\)的区间才符合条件。处理出序列中极大连续全为\(x\)的区间个数及其长度,答案为各个区间答案相加。对于长度为\(l\)的区间,其子区间均符合条件,故答案等于\(\dfrac{(l+1) \times l}{2}\)。
对于\(x \ne y\)的情况,满足条件的区间中肯定不包含小于\(y\)或者大于\(x\)的元素,这样又分成多个区间相加了。对于其中一个区间可以线性处理出答案。
具体就是,假设当前枚举到了\(i\),上一个\(x\)的位于\(px\),上一个\(y\)位于\(py\)。如果\(a_i = x\),那么又有可能出现新的满足条件的区间了,然后新的区间包含\([py, i]\)。
新区间左端点必须大于上一个\(px\),否则会出现重复计数,故新区间左端点的取值有\(py - (px + 1) + 1\)种方案。注意一下初始的时候可能没有上一个\(x\),这个时候可以认为\(py\)之前到子区间左端点都可取。
新区间的左端点已经考虑过重复了,所以右端点不需要考虑,故新区间右端点的取值有\(r - i + 1\)种,其中\(r\)是目前子区间的右端点。
\(a_i = y\)类似。
F - Cards
考虑转成图上问题,就是\(p_i\)到\(q_i\)连边,这样出来的图会是多个相互独立的环构成的,而且每个点的度数都为2,然后问题可以转化成边覆盖方案数。
每个环可以分别算答案,最后乘起来就可以了。
然后因为图中的点,度数都为2,所以问题可以转化成:对于图中的每一个点,和他相连的两条边至少选一条的方案数。
现在是一个环上问题,考虑搞成线性的问题,就是一个连续的序列,每两个连续的元素至少选一个问方案数,这个就是看每个选素选与不选,实际就是一个动态规划。
然后,根据这个解决环上问题的话,用类似的方可以转成线性问题。
G - Dream Team
如果只需要回答一个问题的话,其实就是一个最大费用最大流。
但是他是多次询问,每次流量增加1。
注意到,EK算法每一轮增广其实就是给源点加流,然后用新加的流去增广。之前为了求最大流,所以每次都是给源点加无穷大的流,现在改成每次给他加1的流让他去增广就可以了。
Ex - Rearranging Problem
官方题解。
B站有dls讲解视频。
具体的证明请看上面两个地方,这里只对最后加速DP的计算做一点更详细的补充。
题解中已经提到了有
,其中\(C(n + 1) = \text{#}\{i | 1 \le i \le n, c_i = c_{n + 1}\}\)。
搞出其生成函数,假设\(F_{n} = \sum_{i = 0}^{n} dp_{n, i} x^i\),那么有
,且有\(F_0 = 1\)。
可以看到都是多项式,全部乘起来就得到了\(dp_n\)对应的生成函数。
从前往后乘的话复杂度会炸,可以分治搞,每次尽量均分成两部分然后算出这两部分的结果,再乘起来就是当前位置的答案,可以证明这样搞是\(O(n \log^2n)\)的。