AtCoder AGC 做题记录
AGC
好几把难。
AtCoder Grand Contest 020
D - Min Max Repetition
首先不难发现有最小长度 \(k = \max \{ \lceil \frac {a} {b + 1} \rceil, \lceil \frac b {a + 1} \rceil\}\),并且我们不难发现答案一定是 \(A\) 和 \(B\) 分开成段,每段 \(A\) 个数递减 \(B\) 递增且 \(B\) 前面尽量为 \(1\) 一之类的贪心玩意,总结一下就是 AA...ABA....ABAA.... 和 B....BAB...BAB... 拼起,我们可以去二分这个边界,然后输出即可。做完了。
E - Encoding Subsets
AC
瞪了好久发现直接爆搜做完了的救赎感。
首先对于一段串,其有两种表示方法,一种是整体的 \((?) \times ?\),另一种是一堆 \((?) \times ?\) 拼起来,我们发现后一种相当于前一种加点合并,我们主要考虑前一种。我们设 \(f_{s, 0/1}\) 表示串 \(s\) 是否允许多个 \((?) \times ?\) 拼起来,那么枚举 \(s\) 的前缀 \(pre\),设其对应后缀为 \(suf\),那么显然:
现在只需考虑每一个 \(f_{s, 0}\) 怎么算即可。我们枚举 \(k\) 表示其可以被长度为 \(k\) 的循环节表示,那么设 \(t\) 表示其循环节最大串,不难发现 \(t = s_{0 \dots k} \cap s_{k + 1 \dots 2k}\) 即是这些循环节原来的交,那么直接递归算 \(f_{t, 1}\) 即可。可以证明到只有 \(n ^ 3 + 2 ^ {\frac n 8}\) 种状态(虽然我不会qwq),炸不死,做完了。
F - Arcs on a Circle
拉拉的插。
由于是小数我们允许一定的精度误差,不妨将坐标离散化。假设所有线段起点只能在整数点的 \(m\) 等分点上,那么我们就发现当 \(m\) 越大误差越小,显然 \(m \rightarrow \infty\) 时可以认为没有误差,我们先考虑当 \(m\) 等分时即坐标离散的算法,此时一共有 \(m \times c\) 个点,我们钦定最长线段所在的起点为第 \(1\) 个点,状压 dp,\(dp_{p, s, i}\) 表示集合状态为 \(s\) 段已经使用过了,最后一条放的线段起点为 \(p\),并且覆盖了 \([1, i]\) 的点的方案数,跟着状态转移不难发现方案数就是 \(dp_{2 ^ {n - 1} - 1, mc}\),由于钦定了一条线所以是 \(2 ^ {n - 1}\)。由于没有被钦定的线段一共有 \(n - 1\) 条,那么总次数应该是 \((mc) ^ {n - 1}\),我们不妨猜有结论这是一个 \(n\) 次多项式,每个有 \(x_m = mc\) 和 \(y_{m} = dp_{2 ^ {n - 1} - 1, mc}\),因为 \((mc) ^ {n - 1}\) 为 \(n - 1\) 次所以有 \(n\) 项。我们观察最终的答案:
不难发现当 \(m \rightarrow \infty\) 时 \({x_{m}} ^ {n - 1} \rightarrow \infty\) 因为 \(x_m = mc\),那么其实上面的答案就是多项式的第 \(n - 1\) 次(最高次)的系数。我们直接用离散算出来的坐标拉插一个 \(\infty\) 即可算出来。做完了。
AtCoder Grand Contest 021
C - Tiling
AC
666 做到唐题了。
我们不妨先尽量把所有地方填上横着的(如果 \(m\) 为奇数就会多一列那么不妨将其全填上竖着的),然后再进行调整,若竖着的少了,那么就将一个 \(2 \times 2\) 的两个叠着的横着的换成两个并排的竖着的,如果竖着的数量大于等于要求的就不换了。如果最后满足了竖着的的个数横着的却又少了了那就是无解了,输出即可。但注意一个 corner case 即当 \(n\) 和 \(m\) 都为奇数的时候,可能出现一个:
^<>
v.^
<>v
特判一下即可,若当无解时并且 \(n\) 和 \(m\) 都是奇数,那么把这个玩意放在右下角,重新做一遍看看无不无解即可。做完了。
E - Ball Eat Chameleons
就差一点啊。/ll/ll/ll
我们将每个 B 与 R 配对,如将 RRBB 配对成 RB RB。考虑最优策略,显然不能有单独的 B,并且如果考虑最优,那么只要一个龙最后吃的一个为 R 或 RB 就可以使其最后变为红,并且我们可以让一只一直吃 BR 最后吃一个 R 或 RB,那么我们可以推出充要条件,需要有至少 \(n\) 个 R 或 RB 且最后一个一定要是 R 或 RB,考虑对这个计数。我们考虑枚举非 BR 的个数 \(i\),并确定每个 RB 和 R 的位置,由于钦定了一个,那么其方案数应为 \(\binom{k - 1}{i - 1}\)。手玩可以发现,如果我们钦定了所有的 RB 和 R 的位置,那么其他所有的位置只有像 BBBBBRRRRR 一直放 BR 才能保证所有分出来的 RB 和 R 的位置是固定的,不固定的是会重复的。总结一下,方案数为:
做完了。
F - Trinity
666 怎么还有多项式题。
直接考虑对每一列的限制 dp。设 \(dp_{i, j}\) 表示前 \(i\) 列确定了 \(j\) 行的最小行号的方案数,初始状态和答案显然为 \(dp_{0, 0} = 1\) 和 \(\sum_{i = 0} ^ n \binom n i dp_{n, i}\)。对于转移我们枚举新确定的最小列号的行的个数 \(k\),对这一列的最大行和最小行是不是新确定的分类,有:
化简后面的组合数:
拆开组合数并整理:
注意到这是一个卷积,可以用 NTT 做到单次转移 \(O(n \log n)\)。注意当 \(k = 0\) 的情况不一样,类似的分类有 \(dp_{i, j} \gets dp_{i, j} + (\binom j 2 + j + 1) dp_{i - 1, j}\)。做完了,时间复杂度 \(O(m n \log n)\)。
AtCoder Grand Contest 022
D - Shopping
永远差一步。
由于最后要回到 \(0\),那么火车一定是走了几整个来回,那我们不妨设答案为 \(ans \times 2L\),我们直接算 \(ans\) 即可。对于所有 \(t_i\),我们不妨 \(ans \gets ans + \lfloor \frac {t_i} {2L} \rfloor\) 然后 \(t_i \gets t_i \bmod 2L\),使得所有 \(t_i < 2L\) 方便操作。那么此时,我们考虑答案最多是多少,一定是当火车到了 \(i\),然后等火车走了 \(2L\) 走回来之后再出去,这样贡献是 \(n + 1\)。
我们考虑更优的。设 \(l_i\) 表示能不能从左边进入 \(i\) 后,是否能在下次火车到他右边的时候出去,那么显然有 \(l_i = [2(L - x_i) \ge t_i]\),类似的设 \(r_i\) 表示从左边进去之后下次经过右边能不能直接上车走,其应为 \(r_i = [2 x_i \ge t_i]\)。不难发现对于一个 \((i, j)\) 且 \(i < j \land r_i \land l_j\),能够省掉一个 \(2L\),那么我们要尽量多的配对,反悔贪心即可。设最大配对数为 \(cnt\),那么应有 \(ans \gets ans + n + 1 - cnt\),然后计算答案即可。做完了。
E - Median Replace
666 有限状态自动机是啥。
我们充分手玩,加入我们有 000 直接消为 0 不劣,所有 111 最后消为 1 不劣,因为有可能 111 的中最后的 1 可能会和后面的例如 10 合并是更优的。对于 010 和 101 和 001 等不是纯色的,我们发现就是直接抹掉了其中的 10 或 01,那么我们可以对所有状态建出有限状态自动机,如下图:

直接在上面 dp 计数即可,类似 AC 自动机。做完了。
F - Checkers
666 不早说 \(n ^ 6\) 能过不然做出来了。
由于 \(X\) 极大,不妨把每个 \(X ^ i\) 看成毫不相干的数。考虑将原题的操作转成二叉树形态,每个非叶子向左儿子的边权值为 \(-1\),向右儿子的权值为 \(2\),将 \(X_i\) 填入叶子,对应系数为到根权值积,询问得到的式子的种类数。如果能知道每种系数的出现次数 \(c\),则可直接用多重集排列 \(\frac {n!} {\prod c!}\) 求出来。显然系数一定为 \(\pm 2 ^ k\)。考虑由叶子一直扩展出整个树,我们按 \(k\) 分层,按正负给每层分类,我们考虑 dp,\(dp_{i, j, x, y}\) 表示前 \(i\) 层一共有 \(j\) 个叶子其中第 \(i\) 层 \(x\) 个正 \(y\) 个负,暴力枚举 \(a\) 和 \(b\) 表示有 \(a\) 个正叶子要扩展和 \(b\) 个负叶子要扩展,暴力转移即可,当 \(j = n\) 时算贡献。做完了,细节见代码。
AtCoder Grand Contest 023
C - Painting Machines
AC
唐氏儿。
拆贡献,设 \(f(i)\) 表示第 \(i\) 次染了之后结束不了的方案数,显然其也表示需要染 \(\ge i\) 次的方案数,那么答案显然为 \(\sum_{i} f(i) + 1\)。考虑算 \(f(i)\),考虑前 \(i\) 次的位置的方案数,正难则反考虑容斥,总方案数显然为 \(\binom {n - 1} {i}\),若当第 \(i\) 次后被染完了,那么 \(1\) 和 \(n - 1\) 一定染了,其他的间隔不超过 \(1\),插板得到方案数 \(\binom {i - 1} {n - 1 - i}\),乘上前 \(i\) 次和后 \(n - i - 1\) 次的的顺序 \(i!(n - i - 1)!\) 即可得到 \(f(i)\),总结一下有:
直接计算即可。
D - Go Home
AC
max 讲过。
递归。设求到区间 \([l, r]\),如果 \(s \le x_l\) 或 \(s \ge x_r\) 那么答案显然。否则如果 \(p_l \ge p_r\),那么当 \([l + 1, r - 1]\) 都走完后只剩下 \(l\) 和 \(r\) 时一定会先去 \(l\) 再去 \(r\),那么在 \(r\) 的人的最优策略就是尽量早的让车走到 \(l\),不妨 \(p_l \gets p_l + p_r\) 然后递归区间 \([l, r - 1]\) 即可。当 \(p_l < p_r\),类似的,一定会先去 \(r\) 再去 \(l\),让 \(p_r \gets p_r + p_l\) 然后递归 \([l + 1, r]\) 即可。做完了。
E - Inversions
AC
虽然看了点 hint,但还是当自己做出来了叭。
设 \(buc_i\) 表示 \(p\) 中有多少元素为 \(i\)。不难发现若 \(\exist i \land \sum_{j = 1} ^ i buc_i > i\) 无解。对于随便填合法的方案数,显然有 \(\sum_{i = 1} ^ n \sum_{j = i} ^ n buc_i - n + i\),记为 \(cnt\)。注意到当 \(p_i = p_j\),两者为逆序对的概率为 \(\frac 1 2\)。那么对于 \(p_i < p_j \land i < j\),不妨把 \(p_j\) 看成 \(p_i\),求出方案数 \(cnt \times \sum_{k = p_i + 1} ^ {p_j} \frac {\sum_{x = k} ^ n buc_x - n + k - 1} {\sum_{x = k} ^ n buc_x - n + k}\) 再乘上 \(\frac 1 2\) 的概率,那么这两个位置的贡献就是这一坨。对于 \(p_i > p_j \land i < j\),亦可以将 \(p_i\) 看成 \(p_j\) 去求,但是不难发现求的是顺序对方案数(因为当 \(i\) 最后放的是值 \(p_j\) 的值时显然也是逆序对),用总方案数 \(cnt\) 减掉即可。考虑枚举 \(j\) 算贡献,需要快速算出所有 \(cnt \times \sum_{k = p_i + 1} ^ {p_j} \frac {\sum_{x = k} ^ n buc_x - n + k - 1} {\sum_{x = k} ^ n buc_x - n + k}\) 之和和前面 \(p_i > p_j\) 的 \(i\) 的个数就能算出 \(j\) 的贡献,显然线段树可以维护这个,做完了。
F - 01 on Tree
神仙贪心。
我们设一个块表示内部顺序确定了的一段,初始就是 \(n\) 个独立的块。假设有 \(c0_i\) 表示一个块的 \(0\) 的个数,\(c1_i\) 表示 \(1\) 的个数,那么 \(i\) 在 \(j\) 前的条件应为 \(c1_i c0_j < c1_j c0_i\),每次动态维护改在最前面的块,设其深度最小的点 \(u\) 代表整个块,那么 \(u\) 所在快就应尽量靠前,由于其应在 \(u\) 父亲所在块的后面,那么设其父亲所在块为 \(v\),那么 \(u\) 一定在 \(v\) 的后方,不妨将两个块合并,且将答案加上贡献 \(c1_v c0_u\),一直合并到只有 \(1\) 个块就做完了。
AtCoder Grand Contest 024
D - Isomorphism Freak
AC
简单构造,感觉没到紫,肯库才 2300 呢。
考虑选定点为根,让所有深度相同的点全部同构,这样显然答案最大,构造也是简单的,设直径为 \(d\),最小多彩度显然为 \(\lceil \frac d 2 \rceil\)。考虑算叶子个数。先求出直径一条链,当 \(d\) 为偶数,考虑让中间两个点深度都为 \(1\)(可以理解为两个根),那么每一层(深度)的每个点若要同构,不难发现其儿子数全应相等,应等于原来那一层中儿子个数最多的点,叶子个数就是每层儿子数相乘再乘上一个 \(2\) 应为第一层有 \(2\) 个点。对于 \(d\) 为奇数,可以让最终间的那个点当根做一遍,但不一定最有,不难发现在将其旁边一个点也设置成根,让深度为 \(1\) 的点有两个,这样子最大深度不会变,并且可能叶子数更少,暴力枚举并计算可以做到 \(O(n ^ 2)\),似乎用一堆前后缀的玩意预处理也可以做到 \(O(n)\)。做完了。
E - Sequence Growing Hard
AC
asdfasdfasdff
手玩一下,注意到任意时刻可以向任意数字前面插一个比他大的数,或者在序列最后加一个数。这有两个操作比较烦,我们不妨认为序列最开始有一个 \(0\),这样可以把所有操作转化为像任意数字前面插一个。这样还是不好计,考虑将这玩意看成数,一个数插在了一个数前面看作是其儿子。这下好多了,设 \(dp_{i, j}\) 表示有 \(i\) 个节点根 \(\ge j\) 的树的方案数,\(f_{i, j}\) 表示 \(i\) 个节点最小值大于等于 \(j\) 的森林的方案数。对于 \(i = 1\),显然有 \(f_{i, j} = dp_{i, j} = k - j + 1\)。对于答案,显然为 \(f_{n, 1}\) 或者 \(dp_{n + 1, 0}\)。考虑转移。对于 dp,比较简单,显然为 \(dp_{i, j} = \sum_{t = j + 1} ^ k f_{i, t}\)。对于 \(f\),考虑枚举最先插进来的子树,有:
其中最小插进来的子树的根的插入顺序一定在最前面所以有 \(\binom {i - 1} {i - t}\)。做完了。
F - Simple Subsequence Problem
AC
好水,这真的是黑嘛qwq。
考虑直接 dp,设 \(f_{i, j}\) 表示一共 \(i\) 位字符串为 \(j\) 的被包含次数,先赋初值,然后考虑转移。先从高到低枚举第 \(d\) 为,在从小到大枚举状态 \(s\),设 \(t\) 是 \(s\) 删了第 \(d\) 位后的状态,显然有 \(f_{i - 1, t} \gets f_{i - 1, t} + f_{i, s}\),但是这样会重复,考虑当 \(s\) 的第 \(d\) 和 \(d + 1\) 位相同时不转即可。做完了,由于至多有 \(1 + 1 + 2 ^ 1 + 2 ^ 2 + \cdots + 2 ^ n = 2 ^ {n + 1}\) 个状态,时间复杂度为 \(O(n 2 ^ n)\)。
AtCoder Grand Contest 025
D - Choosing Points
神秘二分图。
注意到距离为 \(\sqrt D_1\) 或 \(\sqrt D_2\) 的点无法构成等边三角形,不难发现这是两个二分图,直接染色即可,可以把图中的点按颜色划分成 4 个集合,一定有一个大小大于等于 \(n ^ 2\),输出即可。
E - Walking on a Tree
神秘欧拉回路。
对于每个路径 \((a_i, b_i)\),我们考虑开个新图,将 \(a_i\) 和 \(b_i\) 建边。考虑当所有点度数为偶,可以找到欧拉回路,所有散步的方向都由欧拉回路经过边的方向决定,显然此时答案最优。但当有的点的度数是奇数,考虑将每个奇数的点像父亲建边,如果父亲还是就以此类推。注意到奇数点的个数是偶数个,这样子向父亲建边后根一定还是偶数度数,是合法的,然后跑欧拉回路即可。做完了。
F - Addition and Andition
神秘模拟。
直接模拟即可,把不会造成 1 减少的压成一步,这样每次 1 都会减少,复杂度均摊线性。
AtCoder Grand Contest 026
D - Histogram Coloring
AC
舒服 dp。
分析一下,设 x 表示红色,设 o 表示蓝色,若一列形如 xoxoxoxo 没有连续的红蓝,那么其转到下一列有两种方案,全部取反或全部不动;若像 xoxoo 这样有连续的,就必须全部取反才行。我们将所有 \(h\) 离散化到数组 a,注意必须要把 \(1\) 加入,设其离散化后对应数组为 \(a\)。考虑 dp 计数,设 \(dp_{i, j}\) 表示第 \(i\) 列,从下到上第一个连续两个出现的位置在 \([a_j, a_{j + 1})\),若 \(j = h_i\) 显然就是没有连续两个。对于答案显然为 \(\sum_{i = 0} ^ {h_n} dp_{n, i}\),对于初始状态 \(dp_{1, i}\),显然有:
计 \(sum(k) = \sum_{i = 0} ^ k 2 ^ i = 2 ^ {k + 1} - 1\),可以差分做到 \(O(\log n)\) 求单个。对于转移,分两种,分别是 \(h_i \le h_{i - 1}\) 和 \(h_i > h_{i - 1}\),分类跟着状态转移即可。做完了,时间复杂度 \(O(n ^ 2 \log n)\),预处理幂做到 \(O(n ^ 2)\),线段树优化做到 \(O(n \log n)\),但咋整都能过。
E - Synchronized Subsequence
AC
构构的造。
显然每组只会有 ab 和 ba 的情况。对于 ab,不难发现其只能放在末尾并越多越好,对于嵌套的 aabb 拆成 ab 更优,不妨设 \(suf_i\) 表示以 \(i\) 开头的后缀最多能凑出多少个 ab。现在考虑 ba,对于 bbaa,假如两个 a 中间还可以插 ba,那么字典序一定更大。那么我们可以注意到,当后面还有 ba 的 a 在后面,遇到了一个 ba 的 b,将其加入字典序更大。我们设 \([i, j]\) 表示以 \(i\) 开头的这样的段,\(O(n ^ 2)\) 可以求出来所有以 ba 的 b 开头的。我们考虑将这么一堆段拼起来,显然最后这些段的字典序应递减,否则删成递减一定更优。我们可以一边单调栈求出来,然后再往末尾尽量多的增加 ab。做完了。
F - Manju Game
?!强强?!
AtCoder Grand Contest 027
B - Garbage Collector
神秘。
枚举捡的次数,不难发现对于每一次一定是从先走到最后面然后走回前面,中途顺便把这一次要捡的给捡上。不难发现每次数量尽量相等不劣,不妨把所有东西的位置按照位置对捡的次数取模,同余的就是同一次捡走,这样显然是不劣的。考虑计算代价,对于一次捡走了 \(p_1 > p_2 > p_3 > \cdots p_k\),贡献为 \(p_1 + \sum_{i = 2} ^ k (p_i - p_{i + 1}) (i + 1) ^ 2\),化简得之后 \(O(n \ln n)\) 计算即可。
D - Modulo Matrix
0 个人想得到。
不难发现 \(m = 1\)。

白色的格子为四周的 lcm 加 \(1\) 即可,调整一下顺序即可做到不超限制。
E - ABBreviate
这种转换到底是怎么能想出来的。
将 \(a\) 转换成 \(1\) 且 \(b\) 转换为 \(2\),考虑一个区间能否被删成一个 \(a\) 或 \(b\) 的充要条件,不难发现为和不变且至少存在一对相邻位置相等,对这个条件 dp 即可。做完了,细节看代码。
F - Grafting
好暴力。
先枚举第一次操作(当然也有可能不操作),目的是找到一个后面都不会动了的点,将其作为根。确定根后,判断其他的点是否有合法操作方式,注意到:
- 若 \(u\) 不需要操作,其父亲也不需要。
- 设 \(u\) 在 A 上父亲为 \(fa\) B 上为 \(fb\),那么操作顺序一定是 \(fb\) 后 \(u\) 后 \(fa\)。
第一个限制直接判断即可。第二个拓扑排序即可。做完了,\(n = 50\) 随便过。
AtCoder Grand Contest 028
B - Removing Blocks
AC
终于有会的了。
把贡献拆到每个位置。考虑 \(j\) 删掉时 \(i\) 要做贡献,不难发现 \([\min(i, j), \max(i, j)]\) 中 \(j\) 要最先删掉,有 \(\frac 1 {\max(i, j) - \min(i, j) + 1}\) 的概率。考虑计算,设 \(f(x)\) 表示 \(\sum_{i = 0} \frac 1 i\),对于位置 \(i\),先考虑计算对自身及左边的贡献,有 \(i!f(i) \binom n {n - i} (n - i)! = f(i) n!\),计算对其右边及自身,有 \(f(n - i + 1) n!\),自己算了两次减去 \(n!\) 的贡献,总结一下对答案一共有贡献:
预处理 \(f\) 后直接计算即可。
C - Min Cost Cycle
AC
10mins 水平。
考虑排序从小到大排序 \(a\) 和 \(b\),取前 \(n\) 小的项的和作为贡献拼凑成边,考虑怎么才能够合法。首先对于正好取了全体 \(a\) 或全体 \(b\) 显然合法,否则对于 \(a\) 和 \(b\) 都有取的情况,手玩一下,发现充要条件是存在 \(i\) 满足 \(a_i\) 和 \(b_i\) 都取,因为只要有一个都取,就会存在一个全都没取,这两个点将换分成两部分,一个部分全是一个边的 \(b_i\) 更小,另一部分全是 \(a_i\) 最小。我们枚举都取了的 \((a_i, b_i)\),然后在加上除了这两个数外的前 \(n - 2\) 小的数的和就是这种情况的答案,逐个取 \(\min\) 即可。做完了。
D - Chords
科迪。
考虑拆贡献到每一个连通分量的两端,\(dp_{l, r}\) 表示 \(l\) 和 \(r\) 联通,内部不一定,且任意 \(x \not\in [l, r]\) 都与 \(l\) 和 \(r\) 不连通,且不管 \(x \not\in [l, r]\) 的 \(x\) 的连边情况的方案数。那么对于答案,显然应为:
其中 \(s_i\) 表示前 \(i\) 个中没有分配的点的个数,\(g(i)\) 表示 \(i\) 个点随便分配边的方案数,显然有递推式 \(g(i) = (i - 1) \times g(i - 2)\) 且 \(g(0) = 1\),可以 \(O(n)\) 预处理出所有值。现在考虑转移,先判断 \([l, r]\) 是否合法,这是简单的,枚举连边 \((i, k)\) 来转移,有:
直接转移做到 \(O(n ^ 3)\)。做完了。
E - High Elements
不会。
https://chatgpt.com/share/6ad489dd-033c-83ee-8c98-9d41cdcd31ea
F - Reachable Cells
不会。
https://chatgpt.com/share/6ad489b5-3ed8-83ee-b43e-0abe65fcf686
AtCoder Grand Contest 029
E - Wandering TKHS
AC
树上差分。
考虑要经过 \(i\) 的点都有 \(d_i\) 的贡献,答案就是一个点自身与所有祖先的 \(d\) 之和,考虑计算这个 \(d\)。
假设现在在点 \(x\) 考虑设 \(f\) 表示根到 \(x\) 的值中的最大值和次大值中靠 \(x\) 更近的那一个,\(s\) 表示更远的那一个,\(cs\) 表示 \(s\) 的儿子且为 \(x\) 的祖先,在维护一个 \(cf\) 意义和 \(cs\) 同理。考虑计算贡献,分讨一下,加入 \(f < s\) 说明 \(f\) 是次大值,不难发现其有贡献 \(d_{cs} \gets d_{cs} + 1\);否则 \(f\) 是最大值,不难发现一定 \(x < s\),手玩一下有 \(d_f \gets d_f + 1\)。做完了。
AtCoder Grand Contest 030
C - Coloring Torus
注意力惊人。
当 \(k \le 500\),构造一个 \(k \times k\) 的每一行一个数即可。
否则,考虑先构造一个形如下面的 \(500 \times 500\):
1 2 3 4 ... n
2 3 4 ... n 1
3 4 ... n 1 2
4 ... n 1 2 3
. ... . . . .
. ... . . . .
. ... . . . .
n 1 2 . . . n-1
这样能容纳 \(500\) 个数。不难发现对于一个斜行,将其从一个数变为两个数交替也合法,将 \(500\) 以上的数插进去即可。做完了。
D - Inversion Sum
我是唐氏儿。
考虑 \(dp_{i, j}\) 表示当下时刻 \(a_i > a_j\) 概率,答案显然为所有 \(2 ^ q\sum_{i < j} dp_{i, j}\),初始状态显然。对于每一个执行,不难发现改变的位置只有 \(O(n)\) 个,暴力转移即可。
E - Less than 3
神奇。
注意到每个 \(0\) 和 \(1\) 的分界线不会消失否则一定不合法,于是我们只保留 \(0/1\) 分界线的位置,操作变成了向左或向右移动一个 \(0/1\) 分界线,由于能从左右增加 \(0\) 或 \(1\) 的段,不妨认为序列最左边和最右边还有无穷个分界线即可。对于算答案,考虑枚举 \(s\) 和 \(t\) 的分界线的对应情况,代价就是每个对应的位置差的绝对值。做完了。
F - Permutation and Minimum
AC
唐唐 dp 题。
考虑所有数的 \((2i - 1, 2i)\) 的情况,我们从大到小填数,当没填的时候,有空着的两种,空了两个和空了一个,我们把空了一个的叫做固定空,因为其位置固定,空了两个填了一个后叫不固定空,我们让后填的决定位置。直接考虑 dp,设 \(dp_{x, i, j}\) 表示 \(x\) 及以上的数都被填了还有 \(i\) 个固定空要填和 \(j\) 个不固定的。设空了一个空的有 \(c1\) 个,设一个没空的有 \(c2\) 个。考虑转移,从 \(dp_{x + 1, i, j}\) 转移出去,后文简记为 \(f\)。考虑当 \(x\) 是一个固定空的一个数时,此时有两种,一是将这个固定空与一个不固定空融合,有贡献:
把这个位置空着等更小的值来填:
考虑 \(x\) 没有出现过,第一种把 \(x\) 填到一个固定空里面:
或者单开一个不固定空:
或者填到一个不固定中,此时考虑 \(v\) 表示还剩多少个位置,不难发现 \(v = n - c1 - c2 - \frac {p0 - (p1 - i) - j} 2\),其中 \(p_0\) 表示前缀大于 \(x\) 个数中在两个都填了的空的数的个数,\(p_1\) 表示在只填了一个空中的个数,有:
答案即为 \(dp_{1, 0, 0}\)。做完了,注意需要滚动数组。
AtCoder Grand Contest 031
C - Differ by 1 Bit
想不到。
分治。对于区间 \([l,r]\),设 \(a\) 是最开始的数,\(b\) 是末尾的数。由于区间长度是偶数,且相邻两个数恰好有一位不同,因此 \(a\) 和 \(b\) 只能有奇数位不同。于是,若初始的 \(A\) 和 \(B\) 有偶数位不同,直接输出 NO。
考虑将 \([l,r]\) 对半分成 \([l,m]\) 和 \([m+1,r]\)。维护当前可以改变的二进制位集合 \(s\),选出 \(a\) 和 \(b\) 不同的一位 \(k\),让左半段所有数的第 \(k\) 位与 \(a\) 相同,右半段所有数的第 \(k\) 位与 \(b\) 相同。这样,两半包含的数互不相交,合起来恰好覆盖当前所有数。
当区间长度大于 \(2\) 时,再从 \(s\) 中选出另一位 \(t\ne k\),令
此时,\(a\) 和 \(c\) 恰好有一位不同;\(c\) 和 \(b\) 有偶数位不同,再翻转第 \(k\) 位,便得到与 \(b\) 有奇数位不同的 \(d\)。同时,\(c\) 和 \(d\) 恰好有一位不同,因此两半之间也可以合法连接。
于是,删去可变位集合中的第 \(k\) 位,分别递归构造起终点为 \((a,c)\) 和 \((d,b)\) 的两半。当区间长度为 \(2\) 时,直接依次填入 \(a,b\) 即可。
用二进制掩码表示 \(s\),可以取
每次递归只需 \(O(1)\) 的操作,总时间复杂度为 \(O(2^N)\),递归栈空间复杂度为 \(O(N)\)。
AtCoder Grand Contest 032
D - Rotation Sort
今天工作量太大了真不想手写了。
https://chatgpt.com/share/6ad4b394-b5f8-83ee-99c5-ac80866d05f8
E - Modulo Pairing
啥都做不出来。。
调整法可得,序列最后长这样:

只要右边都会触发取模,发现分界点越靠左不劣,考虑二分最靠左的分界点,使得右边的两两的和大于等于 \(M\)。做完了。

浙公网安备 33010602011771号