AtCoder Grand Contest 037 学习
考场状况
第一把 AtCoder, 把我校的省队大佬以及另外两个兄弟拉进来组了个车队。两个小老弟原定帮我解决ABC, 最后他们就做了AB, 省队大佬率先切掉E, 我切掉了CD.
没想到名次这么靠前,下回不组车队了。
A. Dividing a String
题意:把一个字符串拆分成最少数量的子串使得相邻两个子串不相等。
笔记:
车队考场做法
同字符的连续段一定按照 $1, 2, 1, 2, \ldots$ 的长度分组,如果不能这么分就吃掉下一种数的头一个,这样不会更劣。如果最后一个数不能分组,就把上一组并进上上组。
题解做法
发现 $1+4, 2+3, 3+2, 4+1$ 至多有两个不合法,因此每段长不超过 $4$, 直接 DP.
B. RGB Balls
题意:给一个长度为 $3n$ 的球序列,红绿蓝三色各 $n$ 个。给 $n$ 个人各分三色球各一个,使每个人拿到的球标号极差之和最小,求分法数。
笔记:
车队考场做法
记一下目前各有多少个 R
, G
, B
, RG
, GB
, BR
, 从左到右扫描,遇到红球时按照 GB
>G
/B
>$\varepsilon$ 的顺序结合,别的类似。方案数即每次选法数之积乘上 $n!$.
题解做法
把三色球的下标分别从小到大排序为 $r_1, r_2, \ldots, r_n$; $g_1, g_2, \ldots, g_n$; $b_1, b_2, \ldots, b_n$. 设 $m_i=\min\{r_i, g_i, b_i\}$, $M_i=\max\{r_i, g_i, b_i\}$. 设第 $i$ 个人持球最小标号为 $a_i$, 最大标号为 $c_i$.
一方面,把 $r_i, g_i, b_i$ 给第 $i$ 个人可以得到极差之和 $\sum_{i=1}^n(M_i-m_i)$.
另一方面,不妨设 $a_1 < a_2 < \cdots < a_n$, 因为有 $k$ 个人持前 $k$ 个红球、绿球、蓝球,所以 $a_k \le m_k$. 因此 $\sum_{i=1}^n a_i \le \sum_{i=1}^n m_i$, 同理可得 $\sum_{i=1}^n c_i \ge \sum_{i=1}^n M_i$, 因此答案不小于 $\sum_{i=1}^n(M_i-m_i)$.
因此答案就是 $\sum_{i=1}^n(M_i-m_i)$. 称 $m_i$ 号球为A类球,$M_i$ 号球为C类球,其余为B类球,那么分球要按照A<B<C的顺序分。从左到右扫描,每次乘上有多少人能接此球即可。
D. Sorting a Grid
题意:给一个 $N \times M$ 网格,每个格子不重复地填有 $1$~$NM$ 的正整数。求一种“先重排每行,然后重排每列,再重排每行”的方案使格子从上到下、从左到右依次有序。
笔记:转化为在两顶点集大小各为 $N$ 的 $M$-正则二分图中找 $M$ 个不相交的完美匹配。因为正则二分图必有完美匹配,所以每次任找一个完美匹配作为答案,删掉它以后图仍然是一个正则二分图(或者无边)。
E. Reversing and Concatenating
题意:给定字符串 $S$, 可以操作 $k$ 次,每次操作为用 $U=SS^R$ 的一个长度为 $|S|$ 的子串代替 $S$, 求字典序最小的最终串。
笔记:不妨设 $S$ 的最小字母为 a
, 其出现次数为 $L$, 那么 $U$ 的最长连续 a
出现次数必然每次都能翻倍,除非翻倍后大于 $N$. 设第一次最长连续 a
出现次数为 $L$, 若 $2^{K-1}L>N$, 答案是 $N$ 个 a
. 否则,除了最后一步外,我们每次都要在末尾暴露出最长连续 a
, 最后一步则是在开头。
车队考场做法
每次取 $U$ 最小子串,如果不是最后一次,就把取出的串取反接着做。
题解做法
枚举第一次选谁,后续的最优决策是确定的,直接算。
F. Counting of Subarrays
题意:给定序列。连续至少 $L$ 个 $k$ 可以合成一个 $k+1$. 求原序列有多少个连续子序列可以合成一个数。
笔记:判断一个序列能否合成一个数可以贪心地做:
- 若序列只有一种元素,则能合成一个数当且仅当序列长度为 $1$ 或不小于 $L$.
- 若序列有多种元素,则找出最小元素的极长连续段,如果有连续段小于 $L$ 则不能合成一个数,否则把 $N$ 个合成 $\left\lfloor\frac NL\right\rfloor$ 个接着做。
考虑整个序列一起做这件事,那么可以设权值 $L_i, R_i$ 分别表示一个元素作为区间左端点、右端点时分别代表多少个元素。
每次取出序列最小值的连续段,先把这些连续段的答案统计进最终答案。
考虑新的 $L_i, R_i$ 的选取,缩起来后最左的点对应了第 $L$ 至第 $2L-1$ 个原先的右端点,次左的点对应了第 $2L$ 至第 $3L-1$ 个原先的右端点,以此类推;左端点的情况类似。
新生成的这些区间上单段统计的答案和原答案重复,要扣除掉。
实现上,拜读 cz_xuyixuan
的代码,很好的思路是,把若干个数的总和对应到原序列的一个区间,从小到大依次插入元素。