AGC 做题合集 #4

书接上回,代码可以在 这里这里(仅包含 AGC024)查看。

  1. AGC009C Division into Two
  2. AGC017D Game on Tree
  3. AGC010C Cleaning
  4. AGC016C +/- Rectangle
  5. AGC008F Black Radius
  6. AGC009D Uninity
  7. AGC010D Decrementing
  8. AGC024C Sequence Growing Easy
  9. AGC024D Isomorphism Freak
  10. AGC024E Sequence Growing Hard

  1. AGC009C Division into Two

    给定 n 个不同的整数 {si},求将它们分成两个集合 X,Y,并且 X 集合中任意两个数的差 AY 集合中任意两个数的差 B 的方案数。

    1N105


    比较 easy 的一个 AGC 题!

    首先可以很轻松地列出状态,f(i) 表示仅考虑 1i 的元素,i 作为最后的 X 集合中最后一个元素的方案数。

    然后我们发现这个不太好统计关于的 Y 的限制,最难的限制应该是上一个元素左边的 Y 和右边的 Y 是否合法,这个难以记录状态,但是如果 AB 呢?我们可以发现,对于当前位置 x,我们枚举上一个位置为 lst,如果 slst+1slst1B,那么就一定是合法的!因为这个是最坏的情况了,对于其他情况,因为 AB,一定合法。

    接下来就是比较 easy 的限制了,考虑 xlst 中间的元素作为 Y 集合是否合法,于是我们可以考虑用队列维护所有合法的转移点,如果出现了两个元素放到 Y 集合中明显合法,那么一段前缀的转移点都要删除,然后转移的时候要满足两个点距离为 A,这个可以 二分/指针 维护,这里我为了方便开了两个队列维护。 ↩︎

  2. AGC017D Game on Tree

    有一棵 N 个节点的树,节点标号为 1,2,,N,边用 (xi,yi)表示。 Alice 和 Bob 在这棵树上玩一个游戏,Alice先手,两人轮流操作:

    选择一条树上存在的边,把它断开使树变成两个连通块。然后把不包含 1 号点的联通块删除

    当一个玩家不能操作时输,你需要算出:假如两人都按最优策略操作,谁将获胜。

    1N2000001xi,yiN


    首先可以猜测,这个和 SG 函数有关,于是我们要猜一个 SG 函数满足可以描述题目中的性质。

    对于树形结构,可以设 f(i) 表示以 i 为根的子树的 SG 函数,因为一个点对应的子树的博弈问题是所有子节点的问题的组合,于是 x 的 SG 函数是子节点的 xor 和。

    初步结论就是 f(x)=xorysonxf(y),然而这样没有考虑到 x 上面挂的边的影响,于是可以进一步猜测挂边就是令 f(x)+1,于是递推式就是:f(x)=xorysonxf(y)+1

    因为猜对了结论,于是不想证明了。 ↩︎

  3. AGC010C Cleaning

    一棵树,第 i 个节点上有 ai 个石头,每次选择两个叶子节点(度数为 1 的节点),将路径上经过的(包括起点终点)所有节点上都取走一个石头,如果路径上有一个点上没石头这个操作就不能进行,问能不能取完所有石头。

    1n105,0ai109


    对于树形问题,首先要找到一个比较好的递归解决方式,通常可以从上而下或者从下而上,对于这个题,如果从上而下,那么意味着有很复杂的 DP 或者决策,于是优先考虑从下而上进行推导。

    于是我们的问题变为,对于一个以 x 为根的子树,它能否完全被消除(只考虑这个子树是否为 YES),如果不能,会怎么样?

    分为两种:

    • 少了路径消除 ax 的部分,这个直接寄了。
    • 多了路径消除 ax 部分,这个可以交给它的父亲进行消除。

    于是有了初步思路:记录 fi 表示消除 i 为根的子树后,还剩下多少路径留给父亲。

    考虑 x 的决策,我们先将 x 的所有儿子的 f 全部加起来 =totf,那么这些路径我们先假设不匹配,那么就会消除 x 上这么多的石头,如果 x 上面还有石头,那么就直接寄了,如果 x 上的石头个数变为负数,我们可以每次合并两条路径,使得 x 上面的石头 +1,一直操作下去,最多可以操作 min{totf2,totfmaxyfy},具体是考虑最大的子树,只能让这个子树和别的子树匹配。注意最好不要直接模拟,不然很容易被一个大小为 4 的菊花,每条边长度为 2 的图卡掉。

    然后就可以求出剩余路径数目了。只要最后 1 的路径剩余为 0 即可。

    这个时候可能会有一点小疑问,fi 真的不能变动了吗?我们发现,让 fi 改变根本还是要拆散一条路径,但是这样会使一个合法的点欠费,于是这是不可能的。 ↩︎

  4. AGC016C +/- Rectangle

    给定整数 H,W,h,w,你需要判断是否存在满足如下条件的矩阵,如果存在,则输出任意一种可能的方案

    • 矩阵是 HW
    • 矩阵的每个元素的权值在 [109,109] 之间
    • 矩阵的所有元素权值和为正
    • 任意大小为 h×w 的子矩阵的元素权值和为负

    比较简单的构造题。

    首先,如果 Hmodh=0Wmodw=0 那么一定无解,因为我们可以通过将整个网格分成不交的矩形使得整体和 0

    接下来假设 Hmodh0

    只要我们可以构造出 W=1,w=1 的方案,然后复制一下,一定满足原来的限制。

    因为 Hmodh0,其实我们可以对于 imodh 讨论一下,如果 imodh=0(i[0,H1]),那么我们就直接来一个 放上面,其他的我们就放一个 εh1,这样必定满足条件,具体实现时 =Hh,ε=1 即可。 ↩︎

  5. AGC008F Black Radius

    Snuke 君有一棵 n 个节点的全白的树,其中有一些节点他喜欢,有一些节点他不喜欢。他会选择一个他喜欢的节点 x,然后选择一个距离 d,然后将所有与 x 距离不超过 d 的节点都染成黑色,问最后有多少种可能的染色后状态。

    两个状态不同当且仅当存在一个节点,它在两个状态中不同色。

    1n2×105subtask:全部都是喜欢的。


    妙妙题!死活想不到怎么去重/kk。

    首先考虑全部都是喜欢的怎么做,记 S(x,d) 表示所有距离 x 小于等于 d 的点的集合,如果 S(x,d)=U(全集),我们直接令这个状态不合法。

    于是有第一个限制d<x 出发的最长路长度,超过这个会变成全集。

    接着考虑重复计算的部分,考虑两个点 x,y 以及两个距离 d1,d2,如果 S(x,d1)=S(y,d2),d1>d2,那么我们提取出 xy 路径上面所有点 {t1,t2,,tk},那么有 S(tj,d1dis(x,tj)) 也是和 S(x,d1) 相同的,我们要钦定一个顺序,满足不会重复计算,于是我们可以钦定我们优先计算小的,也就是 S(y,d2),容斥掉其他的元素,这样的好处就是对于一个 x,合法的 d 一定是一段区间。

    现在,我们要求对于所有和 x 相邻的 kS(x,d)S(k,d1),然后对于这个条件,首先 S(k,d1)S(x,d) 的,而让两者相同,则意味着将整个树以 x 为根,所有距离 k 小于等于 d1 的点(也就是距离 x 小于等于 d2 的点,因为 k 子树里的不管了)就是整个树剔除 k 子树这个部分,求出从 x 除了 k 子树的最长路 t,那么 d2t 的时候,d 就会不合法,即 dt+1这是第二个限制

    于是我们可以求出每个点的 d 的上界 mxid[0,mxi]


    考虑对于不喜欢的点的处理。

    首先喜欢的点还是随便选择 d,但是不喜欢的点可能会因此容斥掉一些喜欢的点的方案,因此需要补上。

    对于一个点 x,考虑所有和它相邻的点 k,当 d 足够大的时候,就会将这个点的子树全部染黑(以 x 为根),如果这个子树里面有一个喜欢的点,那么这时候,这个方案就和从喜欢的点出发没有区别了,我们只要求出 ti 表示所有和 x 相邻有喜欢点的子树中最长路的最小值,这个就是 d 的下界 mni

    以上所有变量都可以通过换根 DP 处理,于是答案就是 1+i(mximni+1)↩︎

  6. AGC009D Uninity

    定义一个单独的节点为一棵 Uninity 0 的树。

    x(x0) 棵 Uninity k 的树全部连到一个节点上形成的树,称之为一棵 Uninity k+1 的树。

    显然,一棵 Uninity k 的树,同样也是一棵 Uninity k+1,k+2,k+3...的树。

    现在给你一棵树,求一个最小的 k 使得这棵树是一棵 Uninity k 的树。

    2n105


    首先,这个合并然后连上点的操作比较复杂,我们可以考虑给他一个等价的东西替代,我们可以给每个点一个标号 ki,同时满足任意两个 ki 相同的点中间一定有比 ki 更大的点,接下来我们只要最小化 ki 即可。

    这个问题还是有点棘手,但是我们可以发现 ki 一定是 logn 级别的,于是 ki 的出现情况可以用一个二进制数表示,接着我们可以考虑随便选择一个点作为根,顺着树形结构从下而上(先确定叶子的状态)进行 DP(这里仅仅是决策),对于一个点 x,我们可以得到一个集合 S 表示所有还没有被其他东西阻挡的点构成的集合(也就是该点到 x 还没有一个比它大的点,我们称为关键点),我们可以先将所有 x 子树关键点合并起来,x 的权值一定是还没有出现的权值中一个,同时如果我们拿出这些关键点出现 2 次以上的元素构成的集合 T那么 x 的权值一定要 max{T}将两个条件结合,就可以找到 x 合法的选取方式,因为更小一定更优,于是找到最小的即可。 ↩︎

  7. AGC010D Decrementing

    题面

    黑板上写着 N 个整数。第 i 个整数是 Ai ,它们的最大公约数为 1

    高桥君和青木君将使用这些数来玩一个游戏。高桥君在这个游戏中是先手,他们将轮流进行以下操作(以下两步相当于一次操作):

    • 选择黑板中大于 1 的一个数,将其减 1
    • 此后,将黑板上所有数全部除以所有数的最大公约数。

    当黑板上的数全部为 1 时,不能再进行操作的人就失败了。两人都选择最好的方式行动,请求出哪边会最终胜利。

    1N1051Ai109,从 A1AN 的所有数的最大公约数为 1


    题解

    比较神奇的博弈问题,只猜对了一半结论/kk。

    首先,如果整个序列形如 k,k,,kn1,k+1,那么当前这个人一定必胜,但是这个还是不够,我们通过继续研究可以发现,k=1,因为上一个人如果料到他操作完了会变成这样,那么他一定令一个 k 变成 k1

    因此,必胜态就是 1,1,,1n1,2 的形式。

    首先,如果序列中出现了 1,那么 gcd 这个判断是没有任何用处了的,可以直接根据偶数的个数的奇偶性判断胜负(结论 1)。

    接着,我们可以暂且抛开繁琐的 gcd,考虑一个更简单的东西,即上面这个条件的变化量,如果目前有奇数个偶数,那么先手可以操作一个偶数,后手无论如何都会使得偶数奇偶性不变,同时无论如何都存活着一个奇数(假设之前有奇数,不然不可能),因此 gcd 始终不会是 2 的倍数,只要先手不断坚持,一定可以到达必胜态,于是先手必胜(结论 2)。

    如果目前有偶数个偶数呢?这个不就是上面先手给后手留下的烂摊子吗?但是还有点不同,前面先手留的烂摊子保证了至少有 2 个奇数(操作前至少一个,后面改出了一个),2 个奇数的情况已经说明了,我们被安排得死死的,于是我们只要考虑只有一个奇数的情况,我们对这个奇数操作一下,然后就会触发除以 gcd 的翻盘机制,只要递归判断即可(结论 3)。

    综上所述,直接讨论后递归求解即可,因为每次递归每个数会 /2,于是复杂度为 O(nlogV)

    启示

    • 对于复杂的操作,我们要学会分析特殊情况,并且从中找到便于刻画状态的变量,然后讨论决策。
    ↩︎
  8. AGC024C Sequence Growing Easy

    有两个长度为 n 的序列:a,x。现在给出 a ,并且已知 x 是空序列,请问至少做多少次下列操作才能使 x 变成 a

    xi=xi1+1

    若无法变成,输出 1,若可以,输出最少的次数。


    简单题。

    假设 {ai} 只有一个位置有数,为 x,我们要得到 x,就要操作 x 次,然后会生成一个 0,1,2,,x 的数列,因为这个会影响前面的东西,于是我们倒着考虑生成 {ai}

    为了方便,可以将序列划分为若干段,满足每一段只有且必须第一个数是 0,其他的数不是 0(一个序列如果前导 0 多了也没有用,少了更不行,因为必须有一个不变)。

    接着倒着考虑生成,每次就是搞一个等差数列,同时讨论一下是否能利用之前的等差数列并不重新造一个,同时要注意如果等差数列起始点已经不是 0 了,要返回 1,次数简单计算即可。 ↩︎

  9. AGC024D Isomorphism Freak

    给定一棵点数为 n 的无根树。对于两个点 u,v , 若有以 u 为根与以 v 为根树同构,则染上同一种颜色。

    可以给这棵树加若干点, 问加完点后树最少能有多少种颜色, 以及在最少颜色的情况下最少有多少个叶子节点。

    n100


    其实完全可以出到 5000,ATC 真的擅长数据范围欺诈。VP 的时候看错了题面,居然打了一个树哈希,然后过不了样例,不然可以早点切的

    手玩样例可以直观感受到我们的最后的图是一个高度对称的图案,也只有这种图案才能使得染色数目最少。

    于是启发我们枚举对称中心(可能在边的中点上哦),接着 DFS,如果当前这个点 xk 个儿子,那么就要求最后生成的树每个深度和 x 相同的点的度数(不考虑父亲)都是 k,这个可以简单取 max 得到,这样构造也是最优的,最后的染色数就是最深的 dep。然后叶子数就是每个深度要求的度数之积即可。

    可能 100 纯粹为了防止炸掉范围。 ↩︎

  10. AGC024E Sequence Growing Hard

    题面

    给定 n, k, m , 问有多少个序列组 (A0,A1,,An) 满足:序列 Ai 的元素个数为 i ; 所有元素都在 [1,k] 内; i[0,n) , AiAi+1 的子序列且 Ai 的字典序小于 Ai+1

    输出在 mod m 意义下的答案。

    n,k300,m109


    题解

    考虑怎么样插入是合法的,假设我们插入一个权值为 v 的数在 x 前面,首先要求是 vx,其次,如果 v=x,那么无非是将 x 的所在连续段延长了 1,会算重,因此 v=x 的情况可以直接不管。同时为了方便,我们在末尾加一个 0

    接着这个问题还是比较棘手,然后有一个神仙的思路:建树!

    我们建立一个 n+1 个节点的树,如果我们让 x 插在 v 前面,那么 x 就是 v 的儿子,同时,每个节点有两个权值 tim[0,n]val[1,k],每个儿子节点的 timval 都要比父亲的大。于是可以记 f(x,i) 表示 x 个节点构成的树,其中根的 vali 额方案数,转移可以枚举最后一个子树大小以及权值,有 f(x,i)=y=1x1f(xy,i)(x2y1)j=i+1kf(y,j),中间的组合数是权值分配方案吗,后面的一个 可以前缀和优化解决,复杂度 O(n3)

    启示

    • 在排列中不断插入数的过程可以往建树上面靠。
    ↩︎
posted @   Werner_Yin  阅读(155)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示