AGC 做题合集 #5
- AGC018D Tree and Hamilton Path[1]
- AGC014D Black and White Tree[2]
- AGC013C Ants on a Circle[3]
- (VP)AGC028C Min Cost Cycle[4]
- (VP)AGC028B Removing Blocks[5]
- (VP 补题)AGC028D Chords[6]
- AGC016D XOR Replace[7]
- AGC016E Poor Turkeys[8]
- AGC016F Games on DAG[9]
- (VP 补题)AGC032D Rotation Sort[10]
AGC018D Tree and Hamilton Path
有一颗 个顶点的树,顶点依次标号 。
第 条边连接着顶点和,且第 条边的长度为 。
有一张 个点的完全图,图上两点之间的边的边权为它们在树上的距离。
求最长哈密顿路径(即不重不漏恰好经过每个点一次)。
。
WA 了 发后终于猜对了结论!
首先,我们令第 条边 中的 为深度更大的点,可以猜测上界为 ,然后手玩样例可以发现,这个上界在哈密顿回路下面是成立的,于是我们只要确定起点终点 ,然后答案就是 。
一个朴素的想法是,我们让 是相邻的,这样我们只要减去一条边的贡献即可,于是选择最小的边。
接着我们会意识到,有的点对是不可能在一起的,比如如果一条边将树分成了两个大小相同的块,那么一定只能选这条边(样例 2)。
接着我就一直以为这是一个特殊情况,于是没有推广,然后一直因为这个 WAWA……
考虑推广上面的结论,一个点对 是不能选择的,当且仅当存在一条边,将树分成了大小为 的两个块并且有 , 在 这个块里面。具体地说,我们每次在两个点中间跳的时候,如果两次都在同一个块内,那么一定是那个大一点的块,不然不能达到上界,而一旦起点终点占了两个点,就会导致中途出现空缺,于是达不到上界。
显然这样的边要么和 相邻,要么和 相邻,扫一扫就可以判断 的合法性了。 ↩︎
AGC014D Black and White Tree
-
给出一颗 个节点组成的树,每个节点都可以被染成白色或者黑色;
-
有高桥(先手)和青木(后手)两个人————高桥可以把任意一个点染成白色,青木则可以把任意一个点染成黑色,每个点只可染色一次。
-
重复上述操作直到所有点都被染色后,只执行一次执行以下操作:
- 把所有青木染成黑色的节点的相邻的白点感染成“次黑色”。
- 次黑色不能继续感染白点。
-
若操作完毕后仍还有白点存在,即高桥(先手)胜,反之则青木(后手)胜。
-
现在给出这棵树,问当前此树是先手必胜还是后手必胜。
。
首先,要求就是一个白点旁边一定要有一个黑点。
因此考虑递归判断,我们考虑最特殊的情况,对于一个叶子 ,如果其父亲 下面有两个以上的儿子,那么可以直接让 变白,之后无论如果都会至少一个叶子是白色,先手必胜。如果 下面只有 ,那么我们直接让 变白,接着 会变黑,那么对于 的父亲 , 是不会有任何影响了,可以视作删除了 两个点了。
于是只要一个非叶子为根,每次考虑最深的叶子然后删除它和父亲即可判断了。
写完了,我们就会发现,这个实际上是要求这个树存在一个完美匹配!于是策略也比较明白了,每选一个点,下一个人直接选这个点的匹配即可。 ↩︎
-
AGC013C Ants on a Circle
有一个长度为 的圆环,上面有 个蚂蚁,位置分别为 ,运动方向为 , 表示顺时针, 表示逆时针。
每只蚂蚁将会同时开始以单位速度运动,如果两只蚂蚁相遇, 那么它们会改变自己的方向继续运动。
求 秒之后每只蚂蚁的位置。
。
这个题比较妙妙妙啊。
首先,如果我们不管改变方向,一只蚂蚁一直爬爬爬, 秒后到的位置集合一定是最后所有蚂蚁到的位置的集合。
如果考虑改变方向,那么每只蚂蚁一定是来回转转转,最后所有蚂蚁的相对位置不变。
考虑从 开始,将环切为一条链,于是我们只要确定了 号蚂蚁最后在第几个(记为 ),我们就可以确定所有蚂蚁的位置了。
对于所有蚂蚁,如果它顺时针穿过 ,那么所有蚂蚁前面都会少一只蚂蚁(除了它),如果逆时针穿过 ,那么所有蚂蚁前面都会多一只蚂蚁。即第一种情况 ,第二种情况 ,于是第一只蚂蚁的位置可以确定了。 ↩︎
AGC028C Min Cost Cycle
- 给定一个 边的有向完全图,每个点有两个点权 和 ,一条边 的边权值的计算方法为 。
- 求边权和最小的哈密顿回路的边权和。
- 对于 的数据,,。
随机数开题 yyds!VP 的时候不信随机数的开题顺序,看了一眼 C 就想 B 去了,结果 B 自闭了,然后再看一眼 C 秒了,接着看 B 也会了。
首先考虑下界应该是什么,我们把 这 个数中的前 小拿出来,这样下界就是这些数之和。
观察样例,我们把前 小的数在原来的序列上面标记一下,如果满足以下几个条件,就是合法的:
- 全部是 A。
- 全部是 B。
- 存在一个 满足, 都没有标记。
然后发现这个结论非常正确,于是只要按照这个结论调整一下选择即可。
不想证明了。↩︎AGC028B Removing Blocks
有 块砖块排列成一行,从左到右编号为 到 。每一个砖块都有一个重量,砖块 的重量为 。 Snuke 会对这些 个砖块执行如下操作:
- 选择一个还没有被移除的砖块,然后移除它。这个操作的代价是与被移除的砖块相邻的砖块(包括它自己)的重量之和。我们定义两块砖 和 是相邻的,当且仅当对于所有 ,砖块 仍然没有被移除。
有 种移除砖块的可能顺序。你需要对于所有可能的顺序计算出移除完所有 块砖块的代价,并计算这些代价的和。由于答案可能非常大,答案需要对 取模。
。
想了半天的 DP 自闭了,结果突然想到计算贡献后这题就没了。首先,我们如果根据点的选择先后顺序构建一棵笛卡尔树,即按顺序选择一个点,然后将整个区间劈成两半,接着递归构造。
于是一个点的贡献就是其在所有笛卡尔树上的深度之和 。
然后一直想着 DP既然已经开始考虑贡献了,我们不妨继续考虑贡献,我们注意到,我们可以枚举 (这里先假设 ),然后计算 是 父亲的方案数,这些方案中就会使得 深度 。
显然,设 ,那么方案数就是 ,注意到这个式子只和 有关,于是枚举 即可计算。 ↩︎
AGC028D Chords
给定一个圆, 圆上均等地放着 个点, 已有 对点之间连好了线段, 从中选择剩下 对点随意连线段(每个点只连一条线段)。
两点联通当且仅当两点在同一条线段上或两点所属于的线段相交, 求所有连边方案中, 联通块的个数和。
。
想了半天终于会了没有限制点对的情况,然后怎么都不会了/kk。
怎么这场一堆考虑贡献的题目啊?!
首先这个题目的圆是无意义的,和直线差不多。
我们考虑取出一个连通块的最左边的点和最右边的点 ,首先这两个点一定属于同一个联通块,其次,这两个点中间的所有点的连边都没有越过 。
于是可以考虑枚举 计算一个连通块是 的方案数,所有方案数相加就是连通块的个数之和。
我们设 表示答案,记 表示 中没有限制连边的点数,记 为如果有 个点没有限制,这 个点两两连边的方案数是多少,显然 ,就是先随意排列,然后消除重复的排列方案。
如果不考虑 在同一个连通块,那么方案就是 ,接着考虑容斥,枚举 所在连通块,减去不合法的即可。
于是 ,直接区间 DP 即可,复杂度 。 ↩︎
AGC016D XOR Replace
一个长度为 序列 ,一次操作可以将某个位置变成整个序列的异或和。问最少几步到达目标序列 ,不行则输出 。
。
对于操作类型问题,如果你觉得它难,就是没有发现操作的不变量 / 更简单的操作表示形式。
这个题就是后者。每次变成异或和是比较玄乎的,但是我们观察整个序列的异或和的变化,比如我们操作的是 ,之前的异或是 ,那么我们操作后这个数字变成了 ,但是异或和就是 了。这个启发可以令 为序列的异或和,然后每次操作就是交换 和任意一个位置上的数字。
令异或和为 ,那么可以达到目标的充要条件就是 。
接着我们考虑最小步数,对于 ,我们就连一条 的边,如果所有的值构成了一个环,并且 是一个孤立点,那么步数就是环长,如果 和所有值一样构成了一个环,那么步数就是环长 ,因为我们不管将所有点校正后 可以不用回来,其他的要回来。
于是答案就是边数 + 连通块数目 - [ 不是孤立点](最后一步让 不回来) ↩︎
AGC016E Poor Turkeys
有 只火鸡,编号为 到 ,有 个人,每人指定了两只火鸡 和 。
- 若 和 都活着, 那么这个人将会等概率地随机吃掉一只。
- 若 和 恰好活着一只, 那么这个人将会吃掉活着的这只。
- 若 和 都已经死亡, 那么只好什么都不做。
注意,第 个人到第 个人每个人依次行动。求有多少个 满足在最终时刻第 只火鸡和第 只火鸡可能都还活着。
很久以前写的,补一发题解。
考虑如果最后要让 活下来,我们应该干什么,肯定要拉一堆火鸡垫背,于是我们可以设 表示如果 最后存活,那么是否一定要拉 垫背。
我们发现,如果正着考虑,每只火鸡生死未卜,无从下手,于是可以发动时间倒流技能!接下来的每次考虑,如果 为 ,那么表示 在后面会被杀,为了保证后面有的杀,于是 在当前时刻一定不能杀,于是可以视为 有一个免死金牌,特殊的 (我们假设最后杀 )。
倒着考虑每个 , ,如果 全被拉去垫背了,因为这次一定会拉一个毙了,于是后面存在某一次没有垫背的了,于是 一定活不到最后;如果 有一个被拉去垫背了,为了让那个时候还能垫背,于是我们可以把另一个也给毙了;如果两个都没有确定是否垫背,那么我们也什么都不能确定。
最后考虑每个最后有希望活下来的 ,如果存在一个 满足 ,那么意味着,我们要在某一回合一定因为保留 要杀了 ,但是这个 又有免死金牌,必须得活下去,后面 需要他垫背,产生矛盾, 一定活不到最后。于是只要 没有公共元素即可活下去。 ↩︎
AGC016F Games on DAG
给定一个个点条边的DAG,对于每条边都满足,号点各一个石头,每次可以沿DAG上的边移动一颗石头,不能移动则输,求所有个边的子集中,只保留这个子集先手必胜的方案个数。
。
首先,如果给定一张图,我们应该如何判断胜负呢?显然,一个点的 函数就是其所有后继点的 的 ,最后只要 点的 不同就是先手必胜了。
我们考虑最后的 SG 函数长什么样:
- 对于 为 的点的集合,我们记为 。
- 内部不能有边。
- , 中的每个点必须要向 中的至少一个点连边。
- 对于 , 中的每个点向 中点连边的情况是任意的。
于是可以考虑 DP 了,我们记 表示只考虑 集合中的点,并且满足 的 函数一样的方案数(, 否则不合法),最后答案就是 了。
考虑转移,我们只要确定当前最小 集合就是了,于是可以枚举 (必须同时包含 / 不包含 1, 2,至于为什么是真子集,是因为如果和 相同,就是全部不能连边,方案为 ,可以直接累加到 ),表示这一个部分的点的 函数是更大的,而 部分的 函数是更小的,如果 包含了 ,那么就可以算出系数递归问题到 ,如果没有包含,那么 的 的相同情况也是不重要的,可以任意连边,这些都是比较好计算的。 ↩︎
AGC032D Rotation Sort
给定一个排列,你可以花费 使一个区间最左边的数跑到最右边,或者花费 的代价使最右边到最左边,求把整个序列变成升序的最少花费。
首先一个点只会被操作一次(我们定义被操作就是指 ShiftLeft 中的最左边元素被操作,ShiftRight 同理),如果操作多次完全可以一次进行。
接着,我们考虑最后不会被操作任何一次的数,显然这些数会形成一个上升的序列,至于其他的数,如果它要比后面的一个在该序列中的数字大,那么就要 ShiftLeft 一次到右边,否则我们视为要 ShiftLeft 一次。
于是可以直接记 表示只考虑前 个元素,其中第 个元素是在这个序列中且所有元素排好序的最小代价,直接根据上面的规律转移即可,复杂度 。 ↩︎
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App