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的计算做一点更详细的补充。

题解中已经提到了有

\[dp_{n + 1, k} = dp_{n, k - 1} + dp_{n, k} \times C(n + 1) \]

,其中\(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_{n + 1} = xF_{n} + C(n + 1) F_n = (x + C(n + 1))F_n \]

,且有\(F_0 = 1\)

可以看到都是多项式,全部乘起来就得到了\(dp_n\)对应的生成函数。

从前往后乘的话复杂度会炸,可以分治搞,每次尽量均分成两部分然后算出这两部分的结果,再乘起来就是当前位置的答案,可以证明这样搞是\(O(n \log^2n)\)的。

posted @ 2022-04-11 00:02  _Backl1ght  阅读(106)  评论(0编辑  收藏  举报