atcoder ARC 做题记录

ARC

这个比 AGC 可做。

120 ~ 160

主要是现场打的,但前几场不是。

AtCoder Regular Contest 225

E - Gap Swap (hard)

自己想出了一个十分难写的做法,看了题解发现自己是唐诗。

首先朴素认为答案上界显然为 \(\sum_{i = 1} ^ n |i - p_i|\),现在我们需考虑会省掉多少步。我们发现对于 \(i < j\)\(p_j < p_i\),我们先交换 \(j\)\(p_j\) 然后再交换 \(i\)\(p_i\),由于 \(j\) 已经归位所以有 \(j = p_j\),根据题目当 \(i\) 被交换到 \(j - 1\) 时能够直接被交换到 \(j + 1\),即省了一步。那么直接求有多少对这样的 \((i, j)\) 那就省了多少步,求一下逆序对即可。做完了。

code

UNIQUE VISION Programming Contest 2026 Summer (AtCoder Regular Contest 226)

D - Penta-Queue

AC

code

AtCoder Regular Contest 227

E - Shift and XOR Switches

asdfasdfasdfasdf

adhoc 题先找性质。我们把异或换成模 \(2\) 意义下的加,那么我们会发现对于按的按钮集合相同但顺序不同是没有影响的,因为两者在去除模 2 后得到的值显然是一样的,加的原理类似 dp 转移,那么加上模 \(2\) 理应也是一样的。且对于若按下了两次 \(x\),手玩一下发现其是等价于按下一次 \(2x\) 的。

我们可以利用这两条性质进行计数。首先顺序是被去掉了。我们按了 \(2 ^ k\)\(x\) 和按了一次 \(2 ^ k \times x\) 等价,那么我们可以将所有 \(a_i\) 分解成 \(b_i \times 2 ^ k\) 的形式且 \(b_i\) 为奇数,设所有 \(b_i = x\) 的数放于 \(s_x\) 中,且 \(buc_{x, k}\) 表示有多少个 \(a_i = x \times 2 ^ k\),那么对于每一个 \(s_x\) 答案应为独立的,即对于 \(\forall i \ne j\) 来说 \(s_i\) 内部的元素怎么取对答案的贡献和 \(s_j\) 内部怎么取无关。那么我们可以对每个 \(x\) 进行 dp,设 \(dp_{i, j}\) 表示形成的长为 \(i\) 的合法二进制前缀中,向第 \(i\) 位贡献的最大进位数量为 \(j\) 的方案数。这是一个数位 dp 状物,设 \(k\) 表示最大能使 \(x \times 2 ^ k \le n\) 的数,那么答案就应为 \(\sum_i dp_{k, i}\)。我们考虑转移,首先有初始状态 \(dp_{0, 0} = 1\),我们设要从 \(dp_{i, j}\) 转移出去,设 \(t = buc_{x, i} + j\),那么考虑不按 \(x \times 2 ^ i\) 的按钮,有贡献:

\[dp_{i + 1, \lfloor \frac t 2 \rfloor} \gets dp_{i + 1, \lfloor \frac t 2 \rfloor} + dp_{i, j} \]

按下,有贡献:

\[dp_{i + 1, \lfloor \frac {t - 1} 2 \rfloor} \gets dp_{i + 1, \lfloor \frac {t - 1} 2 \rfloor} + dp_{i, j} \]

直接转移即可,直接做不好做可以用 map 辅助。每一个数只能且仅能拆成一种 \(x \times 2 ^ k\) 的形式那么只有 \(O(n)\) 种状态,做完了。

F - Erase and Raise

AC

也是自己做出来了。

先找性质。我们设被删掉的位置,前一个为 / 后一个为 \,未被删掉的为 _,我们发现任意一个折线都可以被一个合法的状态弄出来,且是一一对应的,对于序列最后得到的序列 2 1 就长这样:

  _
 / \_
/    \

那么,就不能出现相同高度的 _,因为要求原序列最终要不可操作。我们对这样的折线计数,我们注意到 /\\/ 是不方便去重的,于是我们令我们的折线中不能出现这样的情况,那么长度为 \(n - 2k\) 的折线都应合法。计数考虑 dp,设 \(dp_{i, j}\) 表示一共 \(i\) 个元素,有 \(j\) 个不连续折线段的方案数,初始状态为 \(dp_{0, 0} = 1\) 且答案显然为 \(\sum_{k = 1} ^ {\lfloor \frac n 2 \rfloor} dp_{k, 1}\) 且当 \(n\) 有偶数时多 \(1\) 的方案数(为空)。对于转移,我们枚举这一层要干什么,我们每次转移时都向下扩一层,由于每一个高度只能有一个 _,那么我们可以枚举这一层的 _ 的位置来转移,若这一层没有 _ 那么就只是把所有向下扩一层,一边插一个 /\,有转移:

\[dp_{i, j} \gets dp_{i, j} + dp_{i - 2j, j} \]

向下扩一层,并在某个折线段左或右加一个 _

\[dp_{i, j} \gets dp_{i, j} + dp_{i - 2j - 1, j} \times 2j \]

向下扩一层,并用 _ 合并两个段:

\[dp_{i, j} \gets dp_{i, j} + dp_{i - 2(j + 1) - 1, j + 1} \times j \]

向下扩一层,且多出一个为 _ 的折线段:

\[dp_{i, j} \gets dp_{i, j} + dp_{i - 2(j - 1) - 1, j - 1} \times j \]

由于每个折线最高处必定有一个 _,且每个 _ 高度必定不同,那么若有 \(j\) 段那么耗费最小的长度应为 \((1 + 2 \times 1) + (1 + 2 \times 2) + \cdots = \sum_{k = 1} ^ j 1 + 2k\),由于其和最多为 \(n\) 不难算出最大的 \(j\) 只有 \(\sqrt n\) 级别,显然直接 dp 即可做到 \(O(n \sqrt n)\)。做完了。

code

AtCoder Regular Contest-- 229

究竟是何等的蒟蒻才不能 ak 这样水的 arc???

A - AtCoder Reverse Contest

严肃认为比 B 和 C 都难。

我们注意到对于这样的序列:

ARARARARCARARC

偶数位是 R,奇数位是 AC,可以将其看作将所有的 C 一次走两步依次走到最左边,不可重合,走的次数就是总贡献,假设第 \(i\)C 在第 \(j\) 个奇数位置那么贡献就为 \(j - i\)。那么我们就可考虑构造了,将 \(X\) 拆分成集合 \(s = \{x_1, x_2, \cdots\, x_k\}\) 使得 \(\sum_{i = 1} ^ k x_k = X\),我们把他构造到序列上,把 \(s\) 中的元素排序后,第 \(i\) 小的数 \(x_i\) 位置应在第 \(i + x_i\) 个奇数,由于序列最多长 \(100\) 所以 \(i + x_i\) 最多为 \(50\)。我们尽量让 \(x_k + k\) 尽量小,我们设将 \(X\) 拆成 \(k \times B + b\)\(b < B\),那么此时 \(x_k + k = \lceil \frac X B \rceil + B\),当 \(B = \sqrt X\) 是取得最小,实际当 \(B = 24\)\(x = 600\) 算出来最大的 \(x_k + k\)\(50\) 正好能够。做完了。

code

B - Halving Subtraction

正着不好做倒着做。对于 \(\sum a_i = 0\) 显然答案是 \(0\)。对于其他情况,我们枚举 \(i\),设 \(a_i = 2 a_{i + 1} + d\),若 \(d < 0\) 那么应该无解,若 \(d > 0\) 的话,我们发现如果减一次 \(i \rightarrow i + 1\) 的过程至多出现一次向下取整导致有 \(1\) 的差,差为 \(d\) 那么就至少减了 \(d\) 次,那么直接对所有 \(d\) 去最大值即可。做完了。

code

C - Sum of Average 2

利用下取整公式 \(\lfloor \frac {x + y} 2 \rfloor = \frac{x + y - (x \not\equiv y \pmod 2)}{2}\),原式可化简为:

\[S = \sum_{i=1}^N A_i - \lfloor \frac{A_1 + A_N + k}{2} \rfloor \]

其中 \(k\) 为重排后序列中奇偶性相邻不同的对数。要使 \(S\) 最小,等价于最大化 \(V = A_1 + A_N + k\)。对于奇数和偶数分开排序后大力分讨首尾奇偶性即可。

code

D - Nim_k ?

考虑总和 \(< k\) 时先手失败。总和大于等于 \(k\) ,且有一堆 \(<k\) 时先手必胜。总和大于等于k,每一堆都 \(>=\) k时,相当于可以所有堆都 \(-k\)。做完了。

code

E - Taka and Hashi

考虑维护 3 个并查集,对于三种类型的边。对于类型 2 和类型 3 都在一个连通块里的,将他们所在的类型 1 连通块也合并,找类型 2 和类型 3 都在一个连通块里的可以用 map <pair <int, int>, vector <int> >。然后判断每个点能不能从 \(1\) 走过去只需判在不在类型 1 的同一个联通块内即可。做完了。

code

F - Angst for All Pairs 2

为什么没有场掉呢。

先转化为图上。对于正反面写了 \(u\)\(v\) 就给两者间建一条边,边权就是 \(C_u + C_v\),限制就变成了对于任意点对 \((u, v)\) 那么存在一条边 \((u, t \ne v)\)\((v, t \ne u)\) 且图边权最小,当 \(u\)\(v\) 间没有连边只需其中一个点不是孤点即可,那么我们只要只设置一个孤点就可以避免这样,设置的孤点显然应为 \(C_i\) 最大的 \(i\)。对于 \(u\)\(v\) 间有连边,那么就应两者至少有一个出度为 \(2\)。我们发现我们的答案应是一个森林。那么对于每一颗树,其至少显然应有 \(3\) 个点且应为所有点都连向树中 \(C_i\) 最小的点的菊花玩意。那么我们先考虑只有一棵树,将 \(C\) 从小到大排序,其代价显然为 \((n - 2) C_1 + \sum_{i = 1} ^ {n - 1} C_i\)\(C_n\) 为孤点。我们考虑弄出更多的树来,我们发现当 \(C_i\) 要独立成一棵树,其 \(C_i \ge C_1\),所以 \(C_i\) 的子节点应尽量少因为将其子节点连到 \(C_1\) 上显然不劣,那么只让其有 \(2\) 个子节点即可。我们来算将 \(C_i\) 成一颗树根的代价,设其两个子节点的 \(C\) 之和为 \(sum\),那么当这三个点都连向 \(C_1\) 时三个边的边权和为 \(3C_1 + C_i + sum\)\(C_i\) 独立之后减少一条边,边权为 \(2C_i + sum\),两者相减,得到 \(C_i - 3C_1\),那么从小到大枚举 \(C_{i > 1}\),若 \(C_i - 3C_1 < 0\) 就将树独立,子节点是啥显然不重要。注意由于每棵树至少有 \(3\) 个点那么最多有 \(\lfloor \frac {n - 1} 3 \rfloor\) 棵树。做完了。

code

posted @ 2026-08-27 21:35  ACehomoxue  阅读(26)  评论(0)    收藏  举报