RE:从零开始的AGC被虐(到)生活(不能自理)
「一直注视着你,似近似远,总是触碰不到。」 ——来自风平浪静的明天
AtCoder Grand Contest 001
B: Mysterious Light
设 (f(x, y)) 为上一次反射长度为 (x) ,边界长度为 (y) 的答案,容易观察得到 (f(x, y) = 2 imes lfloorfrac{y}{x} floor imes x + f(y mod x, x))
C: Shorten Diameter
Solution1: 补集转化一下,保留下尽可能多的点。令(dp[u][i]) 表示子树 (u) 里面最深的点距离 (u) 最多为 (i) 能选出的最多点数,转移的时候枚举一下深度最深的子树选的深度,其他子树能选的范围就确定了,前缀和优化一下转移即可。
Solution2: 官方题解的做法好努比啊,比我的辣鸡做法优越到不知道哪里去了。考虑最后删成的树一定有一个重心,可能是一个点或者一条边,直接枚举重心是什么然后把到重心的距离超过阈值的的点删掉,每种情况取个 (min) 就是答案。
solution3: 第一种做法的转移可以分类讨论是否更新最深链,更新的情况直接前缀取一个 (max) ,不更新的情况是有单调性的,每一个区间被谁转移都是确定的,直接用长链剖分+线段树优化复杂度 (mathcal O(nlog k))
D: Arrays and Palindrome
考虑一个长度为偶数 (n) 的回文子串,如果增加限制条件 ([1,n-1]) ,那么其所有字符都相同的,一个长度为奇数 (n) 的回文子串,则需要增加限制条件 ([1, n-1], [2,n]) 才能使得所有字符一样。容易发现当奇数串的个数 (> 2) 时,限制条件数量会不够导致无解。于是可以将奇数串放在收尾,构造第一个和最后一个 (b) 使得中间的偶数串正好长度差 (1) ,注意特判一堆细节
E: BBQ Hard
一道好题,考虑要求的式子是 $frac{1}{2}sum_{i=1}^nsum_{j=1,j eq i}^n C_{a_i+a_j+b_i+b_j}^{a_i+a_j} $ 后面的组合数可以看做是从大小为 ((a_i+a_j) imes (b_i+b_j)) 的棋盘从左上角走到右下角每次向右/向下的方案数。于是可以将 (a_i, b_i) 拆成两个点 ((a_i, b_i), (-a_i, -b_i)) 那么从 ((-a_i, -b_i)) 走到 ((a_i, b_i)) 的方案数就是 (C_{a_i+a_j+b_i+b_j}^{a_i+a_j}) ,实际上可以把所有点放在一起 (dp) ,所有第三象限的点到 ((a_i, a_j)) 的方案数之和减去自己到自己的方案数就是 $sum_{j=1,j eq i}^n C_{a_i+a_j+b_i+b_j}^{a_i+a_j} $ ,最后 (O(n)) 求一下和就好了
F: Wide Swap
神仙题,想了半天看了半天题解才会。将这个排列求逆后变成 (q_{p_i} = i) ,不难证明满足条件的字典序最小的 (q) 对应的 (p) 也是满足条件字典序最小的。但是问题转化到 (q) 上就有一个很优美的性质,每次可以交换的条件变成了 (i, j) 相邻且 (|q_i-q_j|geq k) 。也就是说除了 (|q_i-q_j|<k) 的相对位置不能改变以外,其它点的位置都可以任意改变。推到这一步后有一个小套路,对于所有 (i < j) 且 (q_i) 必须在 (q_j) 前面的点对连一条边,对新生成的 ( ext{DAG}) 求最小拓扑序就是能得到的最小字典序。但是全部连边边数会爆炸,考虑对于 (q_i) 其连边的区间是 ([q_i-k+1,q_i), (q_i, q_i+k-1]) ,实际上对于 (i) 的两个区间分别连后面离其最近的 (j) 就能满足限制,因为 (j) 也和后面点的连边必然包含 (i) 的某个区间,这部分用扫描线从右到左线段树维护即可。
AtCoder Grand Contest 002
B: Box and Ball
维护一下每一个盒子当前的球数以及是否有可能有红球,每次转移如果 (x) 没球了当前就没可能有红球,其余情况红球的可能性具有传递性,修改一下就好了
C: Knot Puzzle
考虑要有一组合法的构造方案必然要存在一段满足 (a_i+a_{i+1} geq L(1 leq i < n)) ,仔细观察可以发现,对于其它的段只要从头尾开始删并让这一段最后删,那么每一次删除的时候当前删的段都会和这一段连一起,长度必然 (geq L)
D: Stamp Rally
如果只有一组询问的话直接二分答案并查集维护一下联通块大小即可,多组询问就直接上整体二分,把询问放在一起 ( ext{check}) 就好了,可以通过 ( ext{BFS}) 的形式处理同一层的区间,这样可以避免并查集的撤销操作
E: Candy Piles
非常精妙的博弈,将 (a_i) 从大到小排之后问题就转化成了每次可以删除最下面一行或者最左边一列,删完的人输。这又等价于从左下角向右/向上双方交替走走到边界的输。设 (f(x, y)) 表示当前走到 ((x, y)) 是必胜态还是必败态。不难证明 (f(x, y) = f(x+1, y+1)) ,考虑此时先手能到达的状态是 (f(x+1, y) /f(x, y+1)) ,如果此时后手到达 (f(x+1, y+1)) 那么显然成立,否则根据先手走的方案其会到达 (f(x+2, y) / f(x, y+2)) ,而如果 (f(x+1, y+1)) 必胜,那么 (f(x+2, y+1) /f (x+1, y+2)) 必然有一个必胜,反之同理。因此只需要考虑从 ((0, 0)) 开始每次 (x, y) 加 (1) 走到某个边界 (f(a, b)) 时的胜负状态即可
F: Leftmost Ball
问题可以转化为一共有 (n+1) 种球,任意时刻前 (n) 种球出现的种类数不能超过 (n+1) 种球的个数,求方案数。可以直接得到一个 (dp) 状态 (dp[i][j]) 表示前第 (n+1) 种球出现了 (i) 个,其他种类的球出现了 (j) 种的方案数。难点在于转移上,一个很显然的转移是 (f[i][j] = f[i-1][j]) ,而添加一种种类的球需要考虑该种球的所有 (k-1) 个位置。这里需要钦点当前新添加的球对应第一个没有对应颜色的第 (n+1) 种球,不然会算重复,那么新一种球放置的总方案数就是 ((n-j+1) imes(k-1)+n-i-1choose k- 2) ,由于球的种类的考虑顺序可以是任意的,(dp) 完还需要乘上 (n!)
AtCoder Grand Contest 003
B: Simplified mahjong
猜一个结论,一段连续都有值的答案就是 (lfloor frac{sum a_i}{2} floor) ,然后合并每一段的答案即可。不妨感性理解一下,先考虑所有元素都和自己组成一些对,那么最后会剩下一些 (1) ,对于每一个 (1) ,其一定能从左右找到另外一个 (1) 合并,即某一位减少一个,当减少到另外一个 (1) 时就合并成了一对,这样最后答案就是 (lfloor frac{sum a_i}{2} floor)
C: BBuBBBlesort!
考虑每一个数的贡献,第二种操作相当于一次移动两格,第一种操作相当于一次移动一格,那么一个数到目标位置的距离是奇数的话就需要 (1) 的代价,否则不需要代价。另外两个需要代价的数一定可以通过若干次二操作使得它们放在一起做,所以最后答案是距离为奇数的数的个数除 (2)
D: Anticube
两个数相乘的结果是一个三次方数,若第一个数的质因子集合为 ((p_1^{a_1}, p_2^{a_2}...)) 第二个数的质因子集合为 ((p_1^{b_1}, p_2^{b_2}...)) 当且仅当 (forall i (a_i+b_i) equiv 0 (mod 3)) ,那么可以把所有数表示成每个质因子的幂次在 (mod 3) 意义下的结果,所以求出每个数对应的结果和补集的结果。对于不能同时选的两个集合,选数量多的那个即可。由于数据是 (10^{10}) ,分解质因数的时候还要加点特技,首先将 (leq {10}^{frac{10}{3}}) 以内的质因数分解掉,剩下的数只有三种情况:1.一个质数,2.两个不同质数的乘积,3.一个质数的平方。对于第一种和第三种情况,判断一下这个数的补集在不在范围内,然后把这个数加进结果里,对于第二种情况,考虑其补集必然不存在,直接 (ans+1) 。
E: Sequential operations on Sequence
先把没有意义的操作用一个单调栈删掉,然后倒着推可以容易发现 (Ans(n, x) = frac{x}{q_{i-1}}Ans(n-1, q_{i-1} + Ans(n-1, x mod q_{i-1}))) ,于是把序列的答案分成两部分维护,其中前面的一部分就是序列中所有数乘上一个相同的系数。对于后半部分,有一个小套路,每次对一个不大于它的数取模最多 (log) 次就取完了,所以每一次二分到第一个比它小的 (q_i) 递归处理。这里答案比较不好算,可以考虑当前情况下每一层操作对总答案的贡献是多少,对于每一个 (q_i) 向下更新这个东西即可。
F: Fraction of Fractal
观察发现,如果存在某一行的两个端点为#且某一列的两个端点为#,那么答案就是1,如果都不存在答案就是第 (k-1) 层图的点数。否则最终的图是若干条链的形态,那么就可以用 (C = V-E) 求联通分量的数量。只有列满足情况和只有行满足情况是等价的,不妨只考虑只有行满足的情况。设 (v) 为初始内部的点数,(e) 为初始水平放向的边数,(e2) 为初始水平方向端点都是#的数量,那么 (V_k=v imes V_{k-1}, E_k = e imes V_{k-1} + e2 imes E_{k-1}) ,用矩阵快速幂优化即可。
AtCoder Grand Contest 004
B: Colorful Slimes
考虑每一种颜色如果是通过若干次魔法得到的,那么总的魔法使用次数等价于使用魔法最多的颜色使用的魔法数,于是直接枚举使用的魔法数,对于每一种颜色在能变换成它的区间里找一个最小的即可。
C: AND Grid
考虑边界都是空的,于是可以把上边界全部给第一张图,下边界全部给第二张图,然后交叉选取每一整列,再让所有原有就是 # 的格子共有,这样两张图就一定是联通的,且只会在 # 处交叉。
D: Teleporter
可以简单证明 (1) 一定在一个自环上。假设 (1) 不在环上,那么环上的点到不了 (1) ,矛盾;假设 (1) 在一个大小大于 (1) 的环上,那么环上的点到 (1) 所需的步长必须等于 (k ext{ mod}) 环的大小,而由于环上的点到 (1) 的步长至少有两个点是不同的,所以产生矛盾。 然后剩下的边就变成了树的形式,问题变为改最少的边使得最大深度不超过 (k),直接贪心即可。
E: Salvage Robots
首先比较好想的一步是模型转换成边界移动,即每次删一行或者一列。后面的地方比较精妙,事实上如果上下左右已经各删了若干次,那么中间肯定有一个矩形里的所有机器人都能直接获得,前提是不删爆。事实上这个矩形的边界可以由当前的上下左右边界直接推导出来。不妨令 (dp[l][r][u][d]) 表示左边界删了 (l) 下,右边界删了(r) 下,上下的定义也类似,此时能获得的最多的机器人数量,直接扩展中间的矩形边界进行转移即可,注意判断删爆的情况。
F: Namori
这题我做到自闭啊,有环的情况根本不会做,最后贺了一下题解决定直接跑路不写2200pts了,那就讲一下1500pts吧。一棵树的情况比较套路,因为只有相邻节点可以操作,于是可以黑白染色后模型转化,通过交换相邻颜色使得原来白色的位置是黑色,原来黑色的位置是白色求最小步数。不难发现如果黑白点数不一样就一定无解,反之一定有界。考虑每一个点与其父亲的边对答案的贡献就是这个点子树里面缺少的黑点/白点数量,因为此时必然要通过这一条边和外界交换。这样可以得到一个下界是 (sum |w_i-b_i|) ,可以证明这个下界是一定取到的。
AtCoder Grand Contest 005
C: Tree Restoring
简单题,考虑树的直径的端点的最远距离一定是直径长度,那么先找到直径长度 (len) ,构造出这么一条链来。观察发现,对于链上的点,分奇偶性讨论,(len) 为奇数时需要 ([lfloorfrac{len+1}{2} floor,len]) 各两个,(len) 为偶数的时候需要 ([lfloorfrac{len+1}{2} floor+1,len]) 各两个, (lfloorfrac{len+1}{2} floor) 一个。对于不在链上的点,根据直径的性质可以简单证明 ([lfloorfrac{len+1}{2}+1 floor,len]) 内的距离都可以通过接在链上的某个非端点节点得到,其它距离必然无法得到,那么能构造的充要条件我们都得到了,直接判断即可。
D: ~K Perm Counting
一道CF题的加强版,基本套路是相同的。考虑容斥,设 (g(i)) 为钦定 (i) 个位置不合法,剩下随便填的方案数,(f(i)) 是恰好有 (i) 个位置不合法的方案数。那么有 (g(i)=sum_{j=i}^nC_{j}^if(j))。二项式反演可以得到 (f(n)=sum_{j=1}^n(-1)^{n-j+1}g(i))。再补集转换一下即可。求 (g) 可以把 (p_i) 与 (i) 的关系当做二分图来考虑,一个不合法的位置对应一条匹配边,匹配边在模 (k) 意义下是若干条折线,拼在一起 (dp) 即可。
E: Sugigma: The Showdown
问题可以转化为红色逃跑蓝色去抓,先考虑 (-1) 的情况,不难发现一个必要条件如果存在一条红色边满足这两个端点在蓝树上距离大于 (2) ,且在红色点被抓住前到达其端点之一,那么蓝色永远抓不住红色。事实上这个条件也是充分的,如果红色没法到达,那么它一定会走到一个在蓝树上深度最大的点,答案就是 (mxdep imes 2),直接求出在不走必要条件边的情况下红色能到达且不被抓的所有点即可,由于在蓝树上距离小于等于2了,乱搞搞就好。
F: ManyEasyProblems
之前单独写了博客,戳这里,考虑每一条边被包含在一个联通块中当前仅当选取了两点分别在这条边链接的两个联通块中,组合数算一下就可以得到,然后发现子树大小相同的点是等价的,按照子树大小分类后就是一个卷积的形式,直接NTT计算即可。
AtCoder Grand Contest 006
C: Rabbit Exercise
每次变换位置等价于将 (E_i) 变成 (E_{i+1}+E_{i-1}-E_i),对 (E) 差分一下令 (d_i=E_i-E_{i-1}) ,然后会发现一次变换之后 (d_i=E_{i+1}-E_{i}+E_{i-1}-E_{i-1}=E_{i+1}-E_i, d_{i+1}=E_{i+1}-E_{i+1}+E_i-E_{i-1}=E_i-E_{i-1}),实际上就是交换了 (d_i) 和 (d_{i+1}) ,然后倍增一下最后交换到的位置即可.
D: Median Pyramid Hard
APIO2018讲课题,二分一个答案 (mid) ,把比 (mid) 小的当作 (0) ,把比 (mid) 大的当作 (1) ,那么问题就转化到 (01) 序列上.观察发现连续两个相同的数会把这两列都变成这个数,01间隔的数上面还是01间隔的,那么只需要判断离第 (n) 个位置最近的连续两个相邻的数是什么即可.
E: Rotate 3x3
这道题令人不明觉厉,考虑一次操作的本质是将外面两列反转后交换,中间一列反转,将列按照奇偶性分类后,发现奇数列的交换对应偶数列的反转,同理偶数列的交换对应奇数列的反转。考虑交换次数和逆序对数的奇偶性是相同的,可以得到一个充分条件,奇数列的逆序对数的奇偶性等于偶数列的反转的列的数量的奇偶性,偶数列的逆序对数同理。事实上这个结论也是必要,不太会证,有没有哪位大爷看到了教教我啊?