AGC 做题合集 #8
代码啥的,可以看之前文章里面的网址,不想再打一遍了……
- "AGC019F Yes or No"[1]
- "AGC044D Guess the Password"[2]
- "AGC026E Synchronized Subsequence"[3]
- "AGC037E Reversing and Concatenating"[4]
- "AGC017E Jigsaw"[5]
- "AGC020E Encoding Subsets"[6]
- "AGC011E Increasing Numbers"[7]
- "AGC033D Complexity"[8]
- "AGC009E Eternal Average"[9]
- "AGC021C Tiling"[10]
AGC019F Yes or No
有 个问题,其中有 个问题的答案是
YES
, 个问题的答案是NO
。当你回答一个问题之后,会知道这个问题的答案,求最优策略下期望对多少。答案对 取模。
。
首先有一个 的 DP,考虑设答案为 ,那么我们的策略是猜 更大的对应的选项。
于是:
把 DP 转到网格图上面,横坐标是 ,纵坐标是 ,这个就是网格上面不断走路的问题。
考虑 这条线,比较特殊,同时我们考虑答案的线的状况,也就是我们从 走到 的过程,而每一次我们选择的答案都是靠近 这条线的方向,通过手玩可以发现,我们无论如何,都会有 的收益,而唯一不确定的就是在 的时候我们的答案是蒙的,于是答案就是 + 所有路径和 相交次数的期望 。
后面这个是好做的,直接枚举在那个节点贡献,就是组合数了。 ↩︎
AGC044D Guess the Password
这是交互题。
有一个密码 ,字符集为 ,你不知道,长度都不知道()。
每次,你可以猜一个密码 ,交互器会告诉你 和 的最短编辑距离(每次可以删除、添加、替换一个字符,最少步数使得 ),在 次询问后给出密码。
。
比较 easy 的 *3100,没有太多拐弯抹角。
长度都不知道就比较 **,考虑先解决长度问题。
我们直接丢一个长度为 的全
a
串,然后就知道a
的个数了!类似的,直接用 的次数不仅问出来长度,甚至问出每个字符出现次数了!问出了长度,我们就可以更进一步了,接下来的策略有几种(我想的):
- 考虑增量构造,每次插入一个字符,然后通过某种奇怪的方式确定这个字符位置。
- 考虑增量构造,每次确定下一个字符。
- 考虑将字符集从 不断拓展到 ,直到到了 。
经过推断后,可以发现最后一种方案比较有前途。
考虑 怎么搞,现在我们有一堆
a
和一堆b
,我们不断确定a
中间空隙的b
的个数,一个比较重要的性质就是如果在 中插入了一个对的字符(比如原来 是 的子序列,插入后还是 的子序列),那么编辑距离会减少。为此,我们可以类似归并排序一样,不断试着把空隙填满,如果填满了,就到下一个空隙中间。可以发现次数是 的。最后一步,我们知道启发式合并,它的本质是小的碰到大的,这个代价是小的大小,而这个题,我们可以每次选择 最小的两个串合并,于是次数就是 了! ↩︎
AGC026E Synchronized Subsequence
有一个长度为 的仅由字符 构成的字符串,且 的个数恰好等于 的个数,都出现了 次。你需要保留一些字符,剩下的字符删掉。对于一个 ,你可以保留从左往右数的第 个 和第 个 。注意,对于这两个字符,只能同时保留或同时删掉,不能只保留其中一个。请你求出能得到的字典序最大的串。
。
猜结论去了,人麻了。
考虑 DP,记 表示目前考虑了 的所有
ab
对的答案。对于第 对
ab
,我们分类考虑保留这一对ab
的最大答案,最后和 取 即可:a
先出现,如果要保留这一对ab
,那么所有在ab
间的a
不能保留,因为比较拉跨,而对于b
如果保留了,还不如删了这一对,于是ab
间都不能保留,记b
后面第一对为 ,那么 。b
先出现,这个是比较优秀的,而这个a
是比较劣质的,于是我们要在这个ab
之间尽量填满b
,直接取出中间所有b
的对,取出后,我们发现,我们会触发连锁反应,于是一直加加加,直到加完了位置,然后继承后面答案。
答案就是 。 ↩︎
AGC037E Reversing and Concatenating
给定一个长度为 的只包含小写字母的字符串 和正整数 ,求进行 次如下操作后:
将 和 的翻转拼接( 在前)得到 ,从 中截取长度为 的子串作为新的 。
字典序最小的 。
。
简单题,只要几个推论即可。
Lemma 1
有效的 不是很大,最多 。
考虑取出最小位置 ,第一次,我们可以让 所在的地方为串的末尾,接下来,每一次,我们复制后,都能让 的个数 ,在 的时间内,直接全部是 了。
Lemma 2
在前 次操作中,我们选择的 满足 ( 反转后的字符串) 字典序最小。
最后一次暴力贪心即可。
为什么呢?首先,我们在前 次操作中,一定是优先让末尾的最小的字符数目尽可能多,其次,是为了让之后的选择更优,结合手玩可以发现,我们只要选择 最小的即可。
综上所述,直接暴力即可,复杂度 。 ↩︎
AGC017E Jigsaw
题面还是看原题面吧,不太好描述。
rnm,不会处理连成环的情况/kk。
首先,对于 这种连接方式合法当且仅当 或者 ,这个启示我们建图,对于一个拼图,如果左边的 那么代表值就是 ,否则就是 ,如果右边的 那么代表值就是 ,否则就是 ,然后左边的代表值向右边的代表值连一条边,容易发现,我们拼起来的方案就对应这若干条路径,每条从 的点出发,不重复的经过每条边,最后在 的点结束。
我们可以根据度数判断是否有解,对于 的点,一定是出度 入度的,对于 的点,一定是出度 入度的。
最后一个问题就是会出现连成一个环的情况,这个可以判断一下对于一个弱连通的图是否是 "卡死" 的,即所有点的入度 = 出度,如果卡死了,那么就会形成环,否则不会。 ↩︎
AGC020E Encoding Subsets
我们定义一个
01
串的压缩是满足如下方式的字符串变化过程:- 如果 合法,那么 也合法(其中 代表字符串拼接)
- 如果 ,那么 也合法(其中
(
,)
,×
为字符, 为数字,算作一个字符,即使其中有 )
我们同时定义 串 是 的子集当且仅当:
现在给你一个 串 ,问它所有的子集的合法变化结果数的总和为多少。
答案对 取模。。
不懂诶,这种题简直就是写出即胜利,
为什么会是 *2900,为什么 luogu 对于 *3400 都要评蓝了而这个题还是黑,难道仅仅是题目标号带了 E?我不理解,但大受震撼。,这种数据范围告诉我们不要高估自己算法的复杂度。
于是可以考虑怎么优雅地写暴力。
我们记 表示 字符串的答案, 表示 字符串必须表示为 的形式(其中 )的答案。
对于 的转移,直接枚举循环节长度 ,然后所有段合一起(对应位置取 ),递归成 的问题。
对于 的转移,我们直接枚举 表示 是不能整花活(不能带有括号,显然方案是 ,其中 为 中 的个数)的, 是必须为 类型方案的, 是任意的,然后直接乘起来。当然,还要加上 压根不整花活的方案,。
调完样例后发现跑得速度很快,手动测一测 ,发现能过?
然后就切了此题。此题唯一难点在于敢于写出暴力 DP。
因为没有看题解,所以解法有点奇怪,似乎有 倍常数,于是抢到了 Atcoder 的第 裂解。
刚看了一下大家的做法,顺便写一写,不过思路是差不多的,但是设计的状态比较巧妙。
设 表示 的答案, 必须表示为单一字符或者由括号括起来的形式。
这样转移的时候就只要枚举一个分界点,并且常数减小了一些。 ↩︎
AGC011E Increasing Numbers
我们说一个数是“递增的”,当且仅当对于它的任意相邻的两位都有左边小于等于右边。
如 , , 是递增的,、 就不是。
现在给你一个数 ,问最少可以被表示成几个递增的数之和。
比如 ,, 。。
做出铜牌题好开心!
不过话说回来,铜牌题就这?对于递增的数,显然类似于洛谷 P2481 [SDOI2010]代码拍卖会,将其拆成若干个 。
接下来就比较 easy 了,从高到低考虑,显然会被低位的进位所影响,于是果断从低位到高位考虑。
假设我们现在有 个这种 的数字(并且,我们目前考虑到了第 位,这些数字后面的 位都是 ,前面的还没有确定),并且我们上一位给了我们进了 次位,如果我们这 个数这一位还是全部设为 ,那么这一位的数就是 ,如果和目标不同,我们就只能通过让 个数这一位为 解决,如果最小的 要 ,那么我们就寄了,因为我们没有办法进行调整,否则我们直接让 减去最小的 。为什么一定是最小的呢,因为这样我们会在后面有更多的自由度。
最后不断操作,如果到了第 位,考虑进位了 的数,如果是 ,那么就是一个合法的方案了,否则就意味着我们的这种 数过多了,可以考虑减少一下(我声称这是可以的,可以通过调整法,在 1 位置大量减少这种数,使得进到 0 的数为 0)。
注意上面的证明不是非常严谨,
但是作为做题人,只要到这一步就差不多了,在本机 Rand 几个数可以发现,一定存在一个分解点 ,满足有 个这种数的情况下就是 OK 的,在 个数的情况下就会寄,多了就只会出现进位到 的数过多的情况。于是这个是有单调性的,可以直接二分答案。复杂度 。
这就是传说中的复杂度带个 吗。↩︎AGC033D Complexity
给定一个 行 列的字符矩阵。
我们定义一个字符矩阵的凌乱度为:
- 若这个字符矩阵中所有字符都相同,则凌乱度为 。
- 否则,则考虑所有的沿水平或者竖直方向的直线,将字符矩阵分成两个不为空的部分,设两个部分的凌乱度分别为 和 ,则整个字符矩阵的凌乱度为 的最小值。
请你求出,给出的字符矩阵的凌乱度是多少。
。
以前的讲课题,知道大概思路,但是没有落实。今天 VP 的是否突然发现有这个题,于是编了编细节,然后写了写。
首先,我们有一个朴素的状态, 表示 为左上角, 为右上角的凌乱度,而这个状态就是 的,而转移还有一个 的复杂度,肯定寄了。
但是我们发现,这个题目的答案是比较小的(),于是可以考虑将状态与答案互换,设 表示从 行到 行从 列开始的凌乱度为 的最右边列是什么,而 表示从 列到 列从 行开始的凌乱度为 的最下的行是什么。
以 转移为例,枚举划分方式,根据列切,那么就是 了,如果按照行切,那么就要根据 来转移,也就是找到最大的 满足 了,而在 固定而 递增的时候 是又单调性的,可以直接双指针求出。
复杂度 。 ↩︎
AGC009E Eternal Average
黑板上有 个 0 和 个 1,我们每次选择 个数字将其擦除,然后把它们的平均数写上去,这样一直操作直到只剩下一个数字,问剩下的这个数字有多少种不同的情况。
答案对 取模
保证 能被 整除。
联赛前写的题目,现在补一发题解。
首先,这种写平均数的题目,我们可以想到建树,一个点对于答案的贡献就是 。
这个时候,比较 naive 的想法,就是直接考虑每次操作了的 个数,但是显然会寄,因为可以操作 个,于是产生了进位。
那么我们可以考虑最后的 进制小数,对于这个进行 DP,然后我们注意到对于原来的小数,每次进位后所有位置的数字和 的结果都是不会变化的,于是只要统计小数的数字之和 和 相同的小数即可。
复杂度 。 ↩︎
AGC021C Tiling
能否在 的棋盘上放 个 的砖和 个 的砖?如果能,构造出方案。
,。
虽然没有看题解,但是并不是完全独立做出来的,因为 WA 到自闭了于是动用了魔法下了两个数据找到了叉点,于是过了。
首先,在 中间有一个偶数的时候,不难得到策略(假设 是偶数):
<><><><>^ <><><><>v <><>^^^^^ <><>vvvvv
而且最多浪费 个:
<><><><>^ <><><><>v <><>^^^^^ <>..vvvvv
其他都是利用最大化了。
对于 都是奇数的情况,我们可以照葫芦画瓢,再整一个类似的:
<><><><>^ <><><><>v <><><><>^ <><>^^^^v <><>vvvv.
最多浪费 个格子:
<><><><>^ <><><><>v <><><><>^ <><>^^^^v <>..vvvv.
然后交上去 WA 了 个点。
下载数据发现是第二种情况有问题。
手玩一下比较小的 case,然后发现在 这种情况下,我们会:
<><>^ <><>v <>...
然后就寄了。
然后有更加优秀的做法:
<><>^ ^<>.v v<><>
这个启发我们再拼上这种方案:
<><><>^ ^<><>.v v<><><> ^<><><> v<><><>
这样两个方案综合,最多浪费一个格子。
注意,我们优先使用
<>
,于是<>
个数为 (如果是 就交换行列构造,然后换回来),不然就会 WA 一个点。 ↩︎
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具