难度标签:[HARD][NORMAL][EASY]


[AGC017C] Snuke and Spells

[NORMAL]

首先考虑怎样的序列是合法的。第一步,删除的一定是 xn,接下来一定是 ynx......

我们将序列长度逐渐变短的过程画在数轴上,那么应该是从 n 开始,发现有 xn,然后向左走 x 步。接下来发现 nx 上值为 y,再向左走 y 步。合法当且仅当这样能走到 0

如果存在 xp,就从 p 向左覆盖长度为 x 的线段的话,合法就相当于 [0,n] 都被覆盖了。

考虑最少需要多少步,才能变得合法。注意到每移动一步,至多多覆盖一个位置,所以设 c 是未覆盖位置,则至少需要 c 步。同时容易构造 c 步的方案。于是只需要每次修改之后维护未覆盖的位置个数即可。


[AGC017E] Jigsaw

[NORMAL]

考虑两个积木什么时候可以拼在一起:

  • 两个都接地。
  • 两个的长度互补。

先不考虑第一个情况的话,相当于当我们遇到了一个右侧接地、长度为 l 的积木,则他要接一个左侧空白长度为 l 的积木。注意到我们总可以将一个积木抽象为 (a,b) 的形式,两个积木 x,y 能拼起来当且仅当 bx=ay

于是,对于每块积木,连边 ab。同时,有一些积木是可以作为最左侧的,一些积木是可以作为最右侧的。这相当于要求我们从一个“左侧点”走一条欧拉路径走到一个“右侧点”(左右侧点是不交的)。注意到欧拉回路是不可行的,因为左右侧点不交。

再考虑第一种情况,相当于就是将整张图拆成若干 “从一个‘左侧点’走一条欧拉路径走到一个‘右侧点’”。这个形式不是很好,考虑建立一个虚点,向所有作为起点的“左侧点”连边,所有作为终点的“右侧点”向虚点连边。这样,答案就是一个欧拉回路。

意思是说,只要我们能给一些“左侧点”添加入度,“右侧点”添加出度,构成一张有欧拉回路的图,那么就合法了。当然,对于每个连通块,都至少要有一个点能和虚点相连(否则就会出现不经过虚点的欧拉回路)。


[AGC017F] Zigzag

[HARD]

考虑逐个确定每条路径。注意到我们只关注当前最右侧的路径。最朴素的做法是每次暴力枚举一条路径,判断是否可行,这是 O(4npoly(n,m)) 的。

不过,我们可以逐步确定,如果我们把一条路径抽象成一个 01 串,那么一条路径 A 能接在一条路径 B 右侧,当且仅当 A 的每个前缀中 1 的个数都 B 的这个前缀中 1 的个数。

于是,我们可以一个一个确定下一步走哪里。设 dpi,S,p,d 表示目前在转移第 i 条路径,目前转移了前 p 步,S 的前 p 位记录完成转移后的状态,后面的位记录前驱状态的这些位,目前与上条线段的距离是 dpopcountd)的方案数。

复杂度是 O(2nn2m),无法通过。我们考虑吃掉 d 这一维。关注到我们的要求只是对于每个前缀,popcount 都不小于前驱而已。假设我们在这一位放了一个 1,那么在接下来的一段时间内,我们可能都是“安全的”,意思是说,我们做的事情不过是将前驱状态的 1 进行一些提前,再在最后加一些 1 而已。

所以,每次如果决定在当前这一位放一个 1 的话,就直接将 p 之后的最近的 1 抓过来用(把 1 的位置设为 0),如果没有 1 了就加一个 1。这样就只要 O(2nnm) 了,可以通过。


[AGC018D] Tree and Hamilton Path

[HARD]

考察了一个较为重要的构造。

首先,考虑哈密顿环的情形。观察一条边的贡献,设这条边两侧的点个数的 minc,则这条边的贡献至多为 2×w×c,即至多在这条边来回这么多次。

实际上,答案是可以顶到上界的。注意到对答案的贡献与两侧点数的 min 相关。我们知道这个值一定 n2从而考虑重心。拿重心为根之后,每个点朝向根的子树都是较大的。

假设现在只有一个重心,则每次我们希望一条路径都能跨越重心。这是可行的,因为若将每棵子树都染色,则每种颜色个数 <n2,一定可以围成一个环,使得相邻颜色不同。构造方式,可以拿出 dfn,将 dfn 为偶数的倒序,隔个插入奇数中,容易证明这样恰好每次会跨越根。

再考虑哈密顿链的情况。如果有两个重心,可以得知中间的边至多经过 n1 次,所以减掉一次中间的边的权值就可以了(剩下的一定有构造方案)。

如果只有一个重心,那么我们可以选择一条与根相连的,权值最小的边,减去即可。


I Am Back

在鸽了不知道多久之后回来了

中间写了一些,题解就懒得补了/emm。

[AGC013F] Two Faced Cards

[NORMAL]

首先如果钦定了每个点选第一个还是第二个,那么就可以直接每个 x 向所有 xY 连边。

如何判断是否存在完美匹配?直接把 X 侧看作 1Y 侧看作 1,每个后缀权值 0 即可(当然也可以从 Hall 定理的角度得到)。接下来考虑贪心地使得尽量多的点选第一个数:

一开始默认他们都选第一个数,当某一刻的后缀权值 <0,选出后缀中的某一个点,切换至“选第二个”。此处明显选择“第二个”最小的点,可以用堆维护。

考虑动态的怎么做。先把 nXn+1Y 按上述方法匹配好,则整个序列的权值是 1(因为一定有一个人没匹配)。如果此时已经不存在合法解了,那以后一定不会有。对于新加入的二元组,我们枚举他选择第一个还是第二个。假设他选择了 x,那从 x 往前的所有前缀权值都会 1,也就是到了 xx 以前的,第一个权值为 0 的位置 p,会出现权值为负数的问题。

同样的,只需要找到 p 的,选“第一个”的,且“第二个”尽量小的元素,切换一下即可。假设切换到 q,那 qq 以前的第一个 0 处又会出现问题,只需要重复上述过程即可。注意到这样不会重复选择同一个元素。

于是可以预处理,每个 0 开始往前“跳”需要多少步,或者无解。然后每次只要找到 p 直接调用即可。


[AGC011F] Train Service Planning

[NORMAL]

尝试手玩。和样例解释的图一样,可以描述为若干段斜率绝对值为 1 的斜线。

对于只有 Bi=1 的情况,首先容易给出一个无解的充分条件:若 2Ai>K 则必然无解,因为甚至塞不进两条不交的,长度为 Ai 的斜线。判完这种情况之后,容易发现就一定能构造一组解了:直接无脑在每个时间段(两条横线之间)随便塞两条斜线就一定可行,只不过可能等待时间很长。

则现在只需要最小化等待时间了,注意到每个时间段看起来非常独立,你可以对每个时间段中任意平移,对合法性没有影响。于是考虑一层一层转移。

如果我们已经得到了上层往这层转移的两个端点 a,b,其中 a 是往下走,b 是往上走,那么只需再确定两个接口 c,d,计算 acdb 即为转移代价。这个问题相当于:在环上有 a,b,c,d 四个点,顺序任意,且只能顺时针移动,要求 acdb 的距离和尽量小。

经过一些讨论容易发现在 a,b,c,d 相对顺序不变的时候,距离是不变的。且 ac 重合 bd 重合都一定不会漏掉最优解。意思是,当我们选择将向下的斜线一直无缝衔接,只调整向上的斜线,不会漏掉最优解。

于是现在的问题中就只剩下一根向上的斜线了,容易将问题转化为:记录当前斜线的端点(需要满足不和向下的斜线相交,这是模意义下的一个区间),然后转移到下一个点,花费两者之间有向距离。经过对这些限制区间的加减,可以把问题变成:

给定 n 个区间 [Li,Ri],你可以一开始选定一个变量 x,第 i 次需要满足 x[Li,Ri],你每次可以将 x(x+1)modK,求最小操作次数。

可以直接设 dpi,j 表示前 i 层后 x=j 的最小花费,那么:

dpi,j=min{dpi1,k+dis(k,j)}

展开 dis(k,j) 得到 jkjk+K,改成维护 dpi,jj 的最小值即可。使用线段树来优化转移,以下是我没想到的部分:

考虑当前区间是 [l,r],那对于 i[l,r],相当于 i 的部分都可以直接转移,>i 的部分要 +K,于是是一个前缀 min 和后缀 min+K 赋值到当前位置。要对区间内每个 i 都进行这个操作。有两种思考方式:

注意到这实际上就是有向地移动所花费的代价,于是对于任意到达 i 的过程,要么是原本就在 i,要么从 i1 来,所以只需要对 l 这一个位置进行修改即可。

另一种想法是考虑对 i,i+1 两者的转移的差异,只有 i+1 这一个点从 +K 变成不 +K。这相当于只要把 i 处的答案和 i+1 原本的答案 chkmin 即可,而在以后,如果 i,i+1 一直同时出现,则没必要再修改 i+1;如果 i,i+1 某一刻不同时出现了,那么必然使用 i 更新了 i+1

所以就可以直接线段树维护了,时间复杂度 O(nlogn)


[AGC018C] Coins

[HARD]

贪心真是太困难了。

首先假设默认都选择 c,然后调整,将 aiaici,bibici

假设现在已经选出了 x 个选 Ay 个选 B,如果不能通过交换变得更优,那么:

iA,jB,ai+bjaj+bi

也就是 aibiajbj。如果我们选定了 AB,那么一定将 aibi 最大的选作 A。于是首先将所有数按照 aibi 从大到小排序,A 一定在一个前缀中选,B 在对应的后缀里选。

因此设 prei,sufi 表示前缀里选 xA,后缀里选 yB 的最大 Δ。然后枚举分界点即可。时间复杂度 O(nlogn)


[AGC019E] Shuffle and Swap

[EASY]

首先,一定是一些 11 之间乱换,然后 10 从通过若干个 11 移动到一个 01 上去。

于是,最后一定会形如若干链,从 10 开始,经过若干 11,以 01 结束。记 100111 分别有 A,B,C 个(显然 A=B)。一定有 A 条链,可以枚举有多少个 C 中的插入链中,然后剩下的 C 中部分直接全排列就行了。

至于 A 条链排列起来,花费 iC 中元素,可以直接 exp。还有一些系数,比如把 A,B 分别匹配,有一个 A! 的系数之类的。复杂度可以是 O(n2)O(nlog2n)O(nlogn)


[AGC020C] Median Sum

[EASY]

首先有简单的 O(n2a) 背包。注意到对于 SS 的补集,他们应该恰好在中位数的左右,因此上述背包的方案数是对称的!因此就只关心拼出过哪些数,而不关心有多少种方案了。只需要 bitset 优化即可做到 O(n2aω)


[AGC015E] Mr.Aoki Incubator

[HARD]

完全不会做/ll

观察最终形态,最后的排列顺序一定是按照 v 从小到大。如果一个点 i 被染色了,那他会染到什么样的点呢?

首先,若 xj>xi,vj<vi,或 xj<xi,vj>vi,那么 i 一定会染到 j(因为互相穿过)。事实证明,找到 xjxi,vjvi 的,vj 最小的 j 作为 lxjxi,vjvi 的,vj 最大的 j 作为 ri 会染黑 [l,r] 中的所有点(还是按 v 排序)。

具体方式可以通过讨论一个 [l,r] 内点的 x 的相对关系。于是问题就变成了,要选择一些区间覆盖 [1,n]。同时,注意到将这些区间按照 ixi 排序后,左右端点分别单调,所以可以通过前缀和来维护,做到线性 dp

标签: none

仅有一条评论

  1. 不知名网友2 不知名网友2

    orz cxy!

添加新评论