Loading

【笔记】AGC选做

AGC053C

长度为 \(2N\) 的排列,分为前面 \(N\) 个和后面 \(N\) 个两部分记作 \(A,B\)。每次可以选择 \(i\) 删去 \(A_i,B_i\) 中较小的,删除后后面的数向前移动,问对于所有的排列最少要删的次数之和。

首先我们考虑对于一个排列怎么算答案,我们假设是将 \(A\) 删空,那么 \(A_i\) 一定是被 \(B\) 中第一个 \(>A_i\) 的数删除,那么排列的代价就是 \(\max\limits_{1\le i\le n}\min\limits_{a_j>a_i}(i - j)\),记得对 \(0\)\(\max\)

考虑计算 \(f_{d}\) 表示代价 \(\le d\) 的次数之和,即可求出答案。也就是对于每个 \(A_i\),在 \(1\sim i+d\) 中一定有比 \(A_i\) 大的数。考虑依次填入 \(A_n\to A_{n-1}\to \cdots\to A_{n - d + 1}\),然后轮流填入 \(B_{n-i},A_{n-d-i}\),最后填入 \(B_{d}\to B_1\)

为什么这么填,因为这样构造之后每次填 \(A\) 只用满足不填入当前最大值即可,而填 \(B\) 则没有任何限制,答案就可以线性求得。

AGC052A

诈骗题,对于任意多个 \(S\),都有 \(n0+n1+0\)\(S+S\) 的子序列。

我们假设 \(S\) 末尾有 \(x\)\(1\),那么构造方式是选择 \(S_l\) 中所有的 \(0\)\(x\)\(1\),和 \(s_r\) 前面 \(N-x\)\(1\),因为末尾所有的 \(1\) 都在 \(S_l\) 中选了,所以匹配到最后 \(Sr\) 一定会露出一个 \(0\)

AGC052B

思维题。

固定根节点 \(x\),我们求树上前缀异或和 \(f_{i}\) 表示根到 \(i\) 路径上 \(w^1\) 的异或和,那么一次操作,等价于交换树边两端的 \(f\)

但是如果树边有一端是 \(x\),那么等价于全局异或 \(f_i\),手算不难发现无论全局异或多少次,都等价于全局异或一次,其余的贡献被消掉了。

所以我们求出 \(g_i\) 表示 \(w^2\) 的异或和,那么问题转化为判断能否将 \(f\) 异或上其中一个数后,重排为 \(g\)

直接枚举异或哪个数是 \(N^2\) 的,怎么快速知道异或的是哪个数呢,题目还有条件 \(N\) 是奇数,那么如果异或了 \(x\),那么 \(x\) 一共被异或奇数遍,所以如果有合法的 \(x\),那么 \(x\) 一定等于所有 \(f,g\) 的异或和。

AGC006F

如果我们将点 \((x,y)\) 看成边 \(x \to y\),那么如果有 \(x\to y,y\to z\),则有边 \(x\to z\)

我们可以独立考虑所有弱连通块,所以如果连通块最长路径 \(\le 2\),那么不会新增边,如果存在自环,存在二元环那么任意两点 \(x,y\) 之间都会连边,更进一步我们发现只要存在长度不是 \(3\) 的倍数的环一定会让所有点两两连边。

因此我们固定一个点 \(x\) 的颜色为 \(col_x\),对于它的出点 \(x\to y\)\(col_y = (col_x + 1) \bmod 3\),如果存在冲突说明有非 \(3\) 倍数的环。

还有情况就是最长路径 \(>2\),并且不存在不合法环的情况,这时所有颜色不同的点之间连边。

AGC005E

博弈题。

对于两棵树我们分别以 \(X,Y\) 为根 DFS 出每个点的深度。

首先考虑无解的情况,如果 \(A\) 树中一条边在 \(B\) 树中对应的路径长度 \(\ge 3\) 显然如果小 \(A\) 到了这条边,那么他可以在这条边两端反复移动,游戏可以无限进行下去。

所以小 \(A\) 的目标是走到这样的边,而小 \(B\) 要组织小 \(A\),由于小 \(A\) 在成功之前走过的边在 \(B\) 树中距离都 \(\le 2\),所以 \(X\) 永远无法跨过 \(Y\),所以只要一个点到 \(X\) 距离小于到 \(Y\) 的距离,那么就可以被小 \(A\) 到达,否则不行。

AGC029E

树上问题。

考虑计算每个点对答案的贡献,我们先求出点 \(x\) 到根路径上的最大值 \(mx\),显然 \(x\) 能使所有 \(mx\)\(x\) 移动一步的子树内的 \(c\) 增加 \(1\)

对于 \(mx\) 子树外一定没有贡献,现在还剩在 \(mx\) 子树内,且与 \(x\)\(lca\) 恰好为 \(mx\) 的点。我们手算一下不难发现只用比较 \(x\) 到根路径上最大值和次大值的相对位置即可。

AGC032D

序列问题。

首先我们将操作看成花费 \(A\) 代价将一个数拎到右边,花费 \(B\) 代价将一个数拎到左边。那么没有被操作的数一定是一个上升子序列,我们考虑计算代价最小的上升子序列。

定义状态 \(f_i\) 表示以 \(P_i\) 结尾的上升子序列的最小代价,\(f_i \to f_j\) 当且仅当 \(P_i < P_j\) 且不存在 \(P_i<P_k<P_j (i < k < j)\)。因为如果存在 \(k\) ,那么可以直接转移 \(f_i \to f_k \to f_j\)

这样限制之后转移就变得方便了很多,因为可以快速计算区间 \((i,j)\) 有多少个数 \(<P_i\) 多少 \(>P_j\),时间复杂度 \(\mathcal{O}(N^2)\)

AGC027D

构造一个 \(N \times N\) 的矩阵,使得矩阵内的数各不相等,且任意相邻两个数 \(\max(x, y) \bmod \min(x, y)\) 相等。

由于只考虑相邻两个数,我们对整个矩阵黑白染色,然后使所有相邻的格子中黑色格子更大。

考虑填入白色格子,那么黑色格子就是相邻四个格子的最小公倍数。那么我们对每个斜对角线固定一个质数,那么每个白格子就是对应两条对角线交点,将两个质数乘起来。那么每个黑色格子最多是四个质数乘起来,在范围之内。

直接求 \(\rm lcm\) 会使得黑白格子有重复的数,我们求 \(\rm lcm + 1\) 即可。

AGC024E

给定 \(n,k\),求有多少个序列组 \((A_0,A_1,\cdots,A_n)\) 满足序列 \(A_i\) 的元素个数为 \(i\)\(A_i\)\(A_{i + 1}\) 的子序列,且 \(A_i\) 字典序小于 \(A_{i + 1}\)\(n,k \le 300\)

\(A_i\) 删掉一个位置即可得到 \(A_{i - 1}\),但并不是删掉任意位置都满足字典序更小。

如果能删除位置 \(x\),说明 \(x\) 后面第一个\(\neq A_{i,x}\) 的数要 \(< A_{i,x}\)。那么对于一段连续的相等的数是等价的,删除其中任意一个的等价的,我们钦定删除最后一个,那么条件就非常优美的,只用满足 \(A_{i,x} < A_{i,x + 1}\)

\(n,k\) 很小,考虑计数 DP,我们记 \(f_{n,k}\) 表示序列长度为 \(n\),所有元素在 \([1,k]\) 的答案。按照套路枚举最小的数 \(w\),和最小的数第一次出现的位置 \(l\),显然 \(l\) 之前和 \(l\) 之后是两个互不相干的子问题,我们只用保证 \(l\) 必须等到后面数删完之后再删。这相当于归并两个序列,直接乘一个组合数即可。

\[f_{n,k} = \sum\limits_w \sum \limits_{l} \binom{n}{n - l + 1}f_{l - 1,k - w}\times f_{n - l, k - w + 1} \]

直接做是 \(\mathcal{O}(n^4)\),我们交换顺序,先枚举 \(i,l\),那么随着 \(k\) 递增,\(\sum f_{l - 1,k - w}\times f_{n - l, k - w + 1}\) 就是一个前缀和,可以优化至 \(\mathcal{O}(n^3)\)

AGC023F

给定一颗树,每个点有点权 \(0/1\),每次可以选择一个没有父亲的节点删除,并将点权加入数列末尾,求数列的最小逆序对数。

显然如果现在可以删的点中存在 \(0\),那么先删 \(0\) 一定不会使答案变差,所以只要有零就优先选零。

这提示了我们,对于零,我们可以把它和它的父亲合并在一起,如果选了它父亲,那么立刻选择它。合并之后每个点有 \(S_0, S_1\) 分别表示块内 \(0/1\) 的个数,显然两个块 \(S,T\),如果 \(S_1 T_0 \le S_0 T_1\) 一定先选择 \(S\),再将 \(S\) 和它的父亲合并,用 set 和并查集在线维护这个过程即可。

时间复杂度 \(\mathcal{O}(N\log N)\)

AGC009D

给定一棵树,求它的点分树的最小深度

首先我们知道点分树的深度大概是 $\log $ 级别的。

考虑将条件转化一下,我们给树上每个点标记一个点分树深度,那么任意两个深度相同的点之间一定存在一个深度最小的点。

根据贪心,每个叶子的深度一定比非叶子大,否则交换叶子和非叶子不会使答案变差。

固定叶子后我们可以依次递推出其余每个点的深度。具体是直接树上 dfs,子树内还有多少没有匹配的深度可以状压表示。

AGC009E

给定 \(n\)\(0\)\(m\)\(1\),每次选择 \(k\) 个数合并成它们的平均数,保证最后剩一个数,问剩下的数有多少种可能。

合并的过程可以刻画成一个 \(k\) 叉树,那么我们记 \(n\)\(0\) 在树上的深度为 \(x_i\)\(1\) 的深度为 \(y_i\),那么树合法的充要条件是 \(\sum k^{-x_i} + \sum k^{-y_i} = 1\)

所以最后的剩下的数一定是一个 \(k\) 进制小数。如果我们把小数点后第 \(i\) 位记作 \(c_i\),满足条件的充要条件是 \((k-1) | (n -\sum c_i)\)。首先 \(n = \sum c_i\) 显然成立,否则每次可以将 \(k\) 个相同的 \(x_i\) 进位成 \(x_i - 1\),其中 \(\sum c_i\) 减小了 \(k-1\),所以只要差是 \(k - 1\) 的倍数即可。

同理对于 \(y\)\(\sum k ^ {-y _ i}\) 也是个 \(k\) 进制小数,要对 \(m\) 满足上述条件。可以数位 DP 解决,复杂度 \(\mathcal{O}(n(n + m))\)

AGC030F

对于长度为 \(2n\) 的排列 \(A\),固定了其中的一些位置,求得序列 \(B_i = \min\{A_{2i}, A_{2i - 1}\}\),问有多少种 \(B\)\(n\le 300\)

对于 \(A_{2i},A_{2i-1}\) 的位置都固定的数对,可以删去。那么剩下 \((-1,-1)\)\((-1,x)\) 两种情况。

数对取 \(\min\) 可以看成数轴上两点匹配取左端点,那么问题转化为匹配。我们将剩下的数从大到小排序,对于出现的数记为 \(1\) 类,其余记为 \(2\) 类,状态 \(f_{i,j,k}\) 表示前 \(i\) 个数,有 \(j\)\(1\) 类数、\(k\)\(2\) 类数没有匹配的方案。

注意一定要从大到小排序,这样每确定一个数,就能确定一个数对。否则对于 \((-1,x)\) 的情况,前面填 \(x+1\) 还是 \(x+2\) 本质相同,但是却计算了多次。时间复杂度 \(\mathcal{O}(n^3)\)

AGC030E

给定两个长度为 \(n\) 的字符串 \(s,t\),不存在子串 \(000/111\),每次操作可以将某一位异或 \(1\),要求整个过程中也不出现子串 \(000/111\),求使 \(s,t\) 相等的最小操作次数。

由于不存在长度为 \(3\) 的段,所以我们把 \(s_i\neq s_{i + 1}\) 的断点记录下来。不难发现一次操作,相当于将断点移动一位,所以我们求出两个串的断点,答案就等价于任意移动断点直到相等的操作次数。

AGC030C

题面

对于 \(k\le 500\) 的情况,直接构造 \(k \times k\) 的矩阵,第 \(i\) 行填 \(i\) 即为合法答案。

现在有 \(k \le 1000\),考虑斜着填数,第 \(i\) 个对角线填 \(i \bmod n + 1\),这样就可以填 \(500\) 个数,同时我们发现一个对角线可以填入两种颜色形如 \(0,1,0,1,\cdots\) 的交替,这样就可以填入 \(1000\) 个数。

AGC030D

给定一个长度为 \(n\) 的数列,和 \(m\) 个操作 \((x,y)\),每次可以选择交换或不交换 \(a_x\)\(a_y\),问所有 \(2^m\) 种情况最终数列逆序对数之和。

考虑将计数问题转化为概率,我们记 \(f_{t,i,j}\) 表示经过前 \(t\) 次操作,\(a_i > a_j\) 的概率。那么对于当前操作 \((x,y)\),有转移 \(f_{t,x,y} = f_{t,y,x} = \dfrac{f_{t - 1, x, y} + f_{t - 1, y, x}}{2}\),同理有 \(f_{t,i,x} = f_{t,i,y} = \dfrac{f_{t - 1, i, x} + f_{t - 1, i, y}}{2}\),由于每次只有 \(2n\) 个状态会改变,所以第一维可以省去,时间复杂度 \(\mathcal{O}(n^2 + nq)\)

AGC025D

给定 \(2n\times 2n\) 的网格,从中选出 \(n\times n\) 个点,使得不存在两个点距离为 $\sqrt{D_1} $ 或 \(\sqrt{D_2}\)

如果两个点之间距离为 \(\sqrt{D_1}\) 就在 \(A\) 图中连边,为 \(\sqrt{D_2}\) 就在 \(B\) 图中连边。粗略估计边数是 \(\mathcal{O}(n^3)\) 有点勉强,但实际边数接只有 \(n^2\) 级别。而我们要选出一个独立集在 \(A\)\(B\) 中没有边,如果图是二分图,那么对两个图分别黑白染色就可以选出 \(1/4\) 个点即为答案。巧的是,建出的图恰好也是二分图。

AGC023E

给定长度为 \(N\) 的序列 \(A\),求所有满足 \(P_i \le A_i\) 的排列 \(P\) 的逆序对数之和。

考虑对每一对位置 \((i,j) (i< j)\) 计算贡献。如果 \(A_i \le A_j\),那么如果 \(A_i < P_j \le A_j\),则有 \(P_j > A_i \ge P_i\) 一定不产生贡献,那么可以把 \(A_j\) 修改成 \(A_i\),然后计算有多少合法排列。此时 \(A_i = A_j\) 那么顺序对和逆序对是相等的,用合法排列数除 \(2\) 即可。

如果 \(A_i > A_j\),那么我们可以用上面相同的办法求顺序对,然后用总的排列数减去顺序对即可。

已知 \(A\) 怎么求合法的 \(P\) 数量。我们将 \(A\) 排序后得到 \(B\)\(B_i\) 对应 \(A_{c_i}\),那么总方案就是 \(tot = \prod (B_i - i + 1)\)

\(B_j\) 修改成 \(B_i\) 怎么计算?不失一般性令 \(B_i < B_j\),还是用上面的公式,就是 \(tot \times \dfrac{B_i - i}{B_j - j + 1}\prod\limits_{k=i+1}^{j-1}\dfrac{B_k-k}{B_k - k + 1}\),也就是形如 \(F(i,j) = tot \times w(i) \times w(j)\times \prod\limits_{k = i + 1} ^ {j - 1} f(k)\) 的形式。我们需要计算所有 \(F\) 的和,考虑固定 \(j\),依次向右移动 \(j\),用线段树维护 \(i\),那么我们只用支持单点修改和全局乘,即线段树的基本操作。

AGC022E

给定一个长度为奇数的 \(0/1/?\) 串,可以将 \(?\) 替换成 \(0/1\),问有多少可能的串是合法的。一个串是合法的当且仅当可以通过每次取长度为 \(3\) 的子串,替换成这 \(3\) 个数的中位数,最后剩下 \(1\)

贪心 + DP。

我们观察到 \(000\to 0\)\(111\to1\),其余都是消去一个 \(01\)。我们要尽量删去 \(0\),然后留下 \(1\),所以优先删除 \(000\)

那么我们开一个栈模拟贪心,将串扫一遍并依次加入元素,如果加入的数 \(1\),就和栈顶的 \(0\) 匹配删除,如果加入的是 \(0\) 且前面有 \(2\)\(0\),就进行 \(000\to 0\)。这样我们栈始终保持底部一段是 \(1\),然后栈顶最多存在两个 \(0\)

再观察一下发现,只要栈中出现了 \(3\)\(1\),那么无论后面怎么加入元素都是合法的。所以我们直接 DP,\(f_{i,j,k}\) 表示前 \(i\) 个数,栈内有 \(j\)\(1\)\(k\)\(0\) 的方案。时间复杂度 \(\mathcal{O}(N)\)

AGC027F

给定两棵 \(n\) 个点的树 \(A,B\),每次可以选择一个 \(A\) 的叶子,删掉该结点的边并连向另一个点,每个点只能选择依次,问将 \(A\) 变成 \(B\) 的最小操作次数。

直接做非常没有头绪。但是考虑到 \(n\) 非常小,考虑用枚举降低思维难度。我们枚举第一次操作。如果第一次修改的点是 \(x\),那么 \(x\) 不能再被修改。我们在两棵树中以 \(x\) 为根。那么 \(A\) 树肯定是从叶子向上修改,一个点能修改当且仅当他子树中的点都被修改了。

但是条件并不充分,我们同时观察到对于 \(B\) 树,如果 \(a\)\(b\) 的父亲,那么如果 \(b\) 先修改,\((a,b)\) 这条边被固定了,\(a\) 就不能修改了。所以一个点能修改还要满足 \(B\) 树中的父亲中需要的修改操作已经完成了。

那么我们就得到了若干 \(a\)\(b\) 先的限制条件,建图跑拓扑即可判断是否可行。

AGC021E

\(N\) 只变色龙,喂 \(K\) 次球,每次可以喂红色或蓝色的球。每只变色龙初始为蓝色,如果被喂了某种颜色的球更多,就变色。问有多少种喂球的颜色序列使得最后每只龙都是红色

考虑贪心,显然先让变色龙变成红色可以少用一个球,否则从蓝色变成红色要多花一个球。

那么我们尽量用一个球让变色龙变成红色,然后消掉一个蓝球。但是情况不可能这么完美,那么对于当前没办法消掉的蓝球,全部喂给 \(1\) 号变色龙。

我们枚举有 \(R\) 个红球,有 \(B = K - R\) 个蓝球,如果 \(R < B\)\(R < N\) 则无解,如果 \(R \ge B + N\),那么对每只龙分配的红球都可以多一个,全部有解。

现在考虑 \(B\le R< B + N\) 的情况。那么最多可以有 \(R - B\) 只龙能多的一个红球,对于它们可以任意吞蓝球,只用保证最后吃的红球更多即可。

那么对于 剩下的 \(N - R + B\) 条龙,它们吃的红蓝球数量相等,那么给他们恰好先喂一个红球再喂一个蓝球最优,这样既满足条件也不浪费球。我们把红球看成左括号,蓝球看成右括号,那么问题转化为 \(R\) 个左括号 \(B\) 个右括号的序列,匹配的括号数 \(\ge N - R + B\)

匹配数不好求,我们将问题取反,条件变为无法匹配的右括号数 \(\le B - (N - R + B) = R - N\) 个,经典折线法问题,可以用组合数 \(\mathcal{O}(1)\) 计算。

需要考虑 corner case \(R = B\) 的情况,因为此时没有龙多吃了一个红球,也就是没有龙能任意吞无法匹配的蓝球。这时候最后一个一定是蓝球,直接将 \(B\) 减一即可。

AGC003C

给定一个排列,操作一是交换相邻两个数,操作二是交换距离为 \(2\) 的两个数,问最少多少次操作一还原序列。

简单题,如果没有操作一,那么奇数位置构成的序列和偶数位置构成的序列可以任意排序,但之间互不相干。所以我们只用找出奇数数列中有多少个偶数即可。

AGC006E

给定一个 \(3\times N\) 的矩阵,每次可以选择一个 \(3\times 3\) 的子矩阵旋转 \(180\)°。问是否能将矩阵排序。

上面一道题的延续,我们将奇数序列和偶数序列分开,一次修改只能交换一个序列中的相邻位置。

同时还要考虑到一列的顺序,顺序记为 \(+\),逆序记为 \(-\)。手算一下发现将交换一次奇数序列,逆序对就行改变,同时偶数序列的 \(-\) 奇偶性改变。交换偶数序列同理。

所以能进行排序的充要条件是奇数序列的逆序对和偶数序列的 \(-\) 的奇偶性相同,对偶数序列同理。由于交换排列任意两个位置逆序对奇偶性改变,所以逆序对的奇偶性直接求出排列最小交换次数即可。时间复杂度 \(\mathcal{O}(N)\)

AGC026E

给定一个由 \(N\)\(a\)\(N\)\(b\) 构成的长度为 \(2N\) 的串,每次可以选择一个 \(i\) 并同时删除第 \(i\)\(a\) 和第 \(i\)\(b\),求能得到的字典序最大的串。

由于恰好 \(N\)\(a,b\),首先想到的就是括号匹配。如果一段内的 \(a,b\) 相等,就可以独立计算,所以我们将原串分成若干段 \(a,b\) 数量相等的子串,且不能再分。

如果这一段以 \(a\) 开始,那么直接选 \(ab\) 会比 \(aa\cdots\) 更优,所以我们贪心选出最多的 \(ab\) 即可。

如果这一段以 \(b\) 开始,我们考虑枚举留下来的第一个 \(b_x\),那么与之匹配的 \(a_x\) 在它后面,它们之间的 \(a\) 一定被删去,而它们之间的 \(b\) 一定被保留,所以删去的是 \(x\) 之前的所有 \(a,b\),而后面的全部保留。我们对所有可能取 \(\max\)

求出了每一段的最大串,我们倒叙枚举,如果加入当前段更优则加。时间复杂度 \(\mathcal{O}(N^2)\)

AGC025F

给定两个长度分别为 \(n,m\) 的二进制数 \(x,y\),进行 \(k\) 次操作,每次令 \(z = x \operatorname{and}y\),然后 \(x \leftarrow x + z\)\(y \leftarrow y + z\)

先考虑直接模拟每次操作,我们从高位向低位枚举 \(i\),如果 \(a_i = b_i = 1\),那么就两位都 \(+1\),然后向后进位。由于高位永远比低位大,所以处理完高位再处理低位不会再影响到高位。

所以我们可以将 \(k\) 次操作同时进行。从高向低枚举每一位,然后记录 \(p\) 表示还可以进行多少次操作,和指针 \(j\)。如果当前位 \(a,b\) 都为 \(1\) 就进行一次操作,并让 \(p\leftarrow p - 1\)。如果当前位有进位则进位。如果两个都不是就退出,否则令 \(j \leftarrow j + 1\),并继续。

直接做是 \(\mathcal{O}(NK)\) 的,但我们发现每枚举一次 \(j\),除了 \(a_j = b_j = 1\)\(a_{j + 1} = b_{j + 1} = 0\) 的情况,其余情况 \(1\) 的个数都会减少。而对于这种情况,等价于将 \(j\) 位的两个一向后移动,并且后面一段是连续的 \(0\)。所以我们只用记录 \(1\) 的位置,对于 \(0\) 段直接跨过即可。

AGC013D

初始有 \(n\) 个黑白球,颜色可以是任意的。现进行 \(m\) 次操作,每次拿出一个球,加入一黑一白两个球,再拿出一个球。问最后有多少可能的拿出球的颜色序列。

每次操作会在颜色序列后面增加两个元素,这两个元素有四种组合,我们枚举这四种情况。如果初始的球颜色是固定的,那么我们直接 DP,设计状态 \(f_{i,j}\) 表示进行了 \(i\) 次操作,此时还剩 \(j\) 个黑球。然后讨论四种转移,\(f_{i,j} \to f_{i + 1, j},f_{i + 1, j + 1}, f_{i + 1, j - 1}\)

但是初始颜色不是固定的,一个颜色序列可以通过多个初始序列得到。我们让每个颜色序列恰好对应最少需要的黑球的初始序列。比如颜色序列 \(BW\) 最少需要 \(1\) 个黑球,\(WBBBWW\) 最少需要 \(2\) 个黑球。我们发现恰好对应的条件就是在 \(f\) DP 的过程中,是否触及 \(j = 0\),只要中间 \(j = 0\),那么就能恰好对应,所以我们再记录状态 \(f_{i,j}\) 表示 \(i\) 个操作,剩 \(j\) 个黑球,是否已经触底的方案。

AGC020D

给定 \(a\) 个字符 \(A\)\(b\) 个字符 \(B\),构造一个字典序最小的字符串,满足连续相同字符个数最大值最小。

显然最小的最大连续字符是 \(k = \left\lfloor\dfrac{\max(a,b)}{\min(a,b) + 1}\right\rfloor\)。手盘一下构造方式,大概是先能填 \(A\) 则填,每填 \(k\) 个用 \(B\) 分隔。一直到剩下的 \(B\) 远多于 \(A\),这时交换策略,能填 \(B\) 则填,每 \(k\) 个用 \(A\) 分隔。

那么我们需要快速计算什么时候交换策略,即计算断点。我们二分答案,假设二分的断点为 \(p\)\(p\) 右边分别有 \(x\)\(a\)\(y\)\(b\)。如果显然 \(x\)\(a\) 最多容纳 \(k(x + 1)\)\(b\),所以如果 \(y \le kx\),那么 \(x\) 可以减小,即 \(p\) 可以继续向右,否则 \(p\) 应该向左。

AGC022D

\(n\) 个商场,第 \(i\) 个商场在数轴上 \(x_i\) 出,你需要在第 \(i\) 个商场连续待 \(t_i\) 分钟。有一辆车周期在 \(0\)\(L\) 之间往返,每分钟走单位 \(1\) 的距离,问从 \(0\) 出发并回到 \(1\) 的最短时间。

车是以 \(2L\) 为周期,如果 \(t_i \ge 2L\),显然对 \(2L\) 取模。

我们先构造一个比较优的可行解。将所有商场按 \(x\) 排序,显然先到达 \(1\) 号商场,然后做 \(2L\) 后的车到 \(2\) 号商场,依此类推,一共需要 \((n + 1)\times 2L\) 的时间。

但是不一定每个商场都要等 \(2L\),如果一个商场从左边进入,下一次来车是 \(2(L-x)\) 分钟后,如果 \(2(L-x) \ge t\),那么就可以搭上,我们记为 \(l_i = 1\),同理如果右边进入可以搭上 \(2x\) 分钟后的车记作 \(r_i\)

观察一下发现如果 \(l_n = 1\) 可以少跑一趟,如果 \(t_i = 0\) 可以少跑一趟,如果 \(r_i = l_j = 1,(i < j)\) 可以少跑一趟。前面两种情况特判一下,最后一种情况贪心用栈匹配即可。

AGC023D

\(N\) 栋楼,现在所有人从位置 \(S\) 出发,在一辆车上,其中有 \(P_i\) 个人要回到位于 \(X_i\) 的第 \(i\) 栋楼。每到一栋楼该楼的人都会下车。现在每一刻都进行一次投票,每个会投给让自己更快到家的方向,车子会向票多的方向走,问所有人都到家的所花费的时间。

博弈题,第一眼看每个人都会直接投给自己家的方向。但是仔细想一下会发现问题,比如某个人家在正方向,但是未来到家前某个时刻支持反方向的人更多,那么迟早都要往回走,他选择投反方向会使这个时刻提前。

直接这么看非常没有头绪,我们考虑倒着想,如果最后只剩下两个人肯定是比谁更多。现在考虑 \(1\sim N\),如果 \(P_1 \ge P_n\),那么车子在到达 \(n\) 之前,一定会被第 \(1\) 栋的人拉走,所以在到达 \(1\) 栋前是不可能到 \(n\) 的,那么 \(n\) 栋的人肯定会一直支持往 \(1\) 走。所以我们令 \(P_1 \leftarrow P_1 + P_n\),然后删掉 \(n\),归纳下去即可。

AGC027E

给定只包含字符 \(a,b\) 的串 \(s\),每次操作可以将 \(aa\to b\)\(bb \to a\)。问可以得到的本质不同字符串数量。

构造,贪心,DP。

我们构造 \(a\to 1\)\(b \to 2\),那么一次操作就是相邻两数相加后 \(\bmod 3\)。最后我们得到的字符串 \(t\),每个字符 \(t_i\) 一定对应 \(s\) 的一段,所以我们等价于求 \(s\) 的划分方案。

我们考虑一段 \(s\) 是否能缩成一个字符,必要条件是这一段的和 \(sum \bmod 3 = 1/2\),但是特殊情况 \(abab\cdots\) 交替的串不能缩,其余的串一定能缩成一个字符,因为我们每次选择 \(xx(xx)\to xyx\)\(x(xx)y \to y\) 一直操作下去即可。

怎样划分才能不重不漏,模仿子序列自动机的思想,我们每次划分的一段一定是最段的一段。比如从 \(i\) 开始的 \(s(i,j)\)\(s(i,k),j < k\) 都可以缩成 \(a\),那么 \(s(j + 1, k) = 0\),所以我们考虑将这一段 \(0\) 留给后面一定不劣。贪心的用 \(s(i,j)\) 匹配即可,用 DP 统计答案。

AGC024F

给定若干个长度 \(\le N\)\(0/1\) 串,求最长的字典序最小的字符串,是最少 \(K\) 个给定串的子序列,\(N\le 20\)

\(N\) 很小,考虑状压。由于是子序列问题,优先考虑子序列自动机。

所以我们设计状态 \(f[S][T]\) 表示当前的串是 \(S\),在自动机上匹配的结点后面的串是 \(T\) 的方案数,初始化 \(f[0][U] = 1\)\(U\) 为给定串,枚举 \(S,T\),然后计算 \(T\) 中第一个 \(0/1\) 转移。

由于 \(S,T\) 的总长度 \(\le N\),所以我们可以把 \(S,T\) 压缩到一起,状态变为 \(f[p][q][ST]\)\(p,q\) 分别表示 \(S,T\) 长度。虽然状态看起来很吓人,但理性分析一下时间复杂度是 \(\mathcal{O}(N2^N)\),注意用 vector。

AGC028C

给定 \(N\) 个二元组 \((a_i,b_i)\)\(i,j\) 之间边的点权是 \(\min(a_i,b_j)\),求最小哈密顿回路。

观察到贡献恰好 \(N\)\(a,b\),我们考虑是否能选择 \(a,b\) 中最小的 \(N\) 个。那么就需要知道什么情况是合法的。

那么对于二元组,产生贡献的为 \(1\),那么有 \(00,01,10,11\) 四种情况。由于 \(a,b\) 数量相同,所以 \(00,11\) 的数量相同。所以只要存在 \(00/11\),那么可以有任意个 \(01/10\)。否则只有全部为 \(01\)\(10\) 合法。即存在且仅存在 \(01/10\) 的情况为非法。

最小的 \(N\) 个非法,说明每组恰好一个。那么将第 \(N\) 个替换成第 \(N+1\) 或第 \(N+2\) 个中至少有一个合法。注意将第 \(N - 1\) 替换成 \(N+1\) 会比将 \(N\) 替换成 \(N + 2\) 更优,需要判断一下。

AGC028D

圆上 \(2n\) 个点,有 \(k\) 对点连了一条线段,你需要给剩下 \(2(n-k)\) 个点配对连边。如果两个点相连或能通过相交的线段到达,则连通。求所有连边方案的连通块数之和。

圆上不好做,直接看成 \(2n\) 个点的排列。那么两条线段 \((i,j),(x,y)\) 相交就是 \(i < x < j < y\)

计数经典方法,计算贡献。我们考虑对每个连通块计算对多少方案产生贡献。为避免重复计算每个连通块以块中最小点和最大点为特征。那么我们记 \(f_{l,r}\) 为区间 \([l,r]\) 中,存在特征为 \((l,r)\) 的连通块的方案数。为便于计算,我们记 \(g_{n}\) 表示 \(n\) 个点任意配对方案,显然有 \(g_n = (n - 1)g_{n - 2}\)

考虑容斥,如果区间 \([l,r]\) 中没有已经固定的连到区间外的点,那么总方案是 \(g_{s(l,r)}\)\(s\) 表示区间内没有配对的点数。然后减去 \(l\) 没有和 \(r\) 连通的方案,那么枚举 \(l < k < r\) 表示 \(l\)\(k\) 连通,总方案是 \(\sum \limits_k f_{l,k} g_{s(k + 1, r)}\)。时间复杂度 \(\mathcal{O}(N^3)\)

AGC028E

给定一个长度为 \(N\) 的排列 \(P\),将排列分成两个子序列。\(s_i = 0\) 表示属于第一个子序列,否则是第二个。求字典序最小的 \(s\),使得两个子序列的前缀最大值个数相等。

难度非常高的一题。

前缀最大值可以标记为某个数比它前面的数都大,这样的数我们记作 \(H\) 数。一个比较明显的观察,对于原排列的 \(H\) 数,无论分到哪个子序列都还是 \(H\) 数。

要求字典序最小,按位考虑,每次试填当前位是否为 \(0\)。那么问题转化为判定。如果现在 \(A,B\) 子序列中 \(H\) 数的数量分别为 \(C_A,C_B\),那么当前位 \(p\) 后面的序列,需要能划分成两个子序列使得 \(H\) 数之差为 \(C_A - C_B\)

一个很重要的结论:现在将序列 \(U\) 分成两个子序列 \(A,B\),如果在 \(A\) 中是 \(H\) 数,在 \(P\) 中不是 \(H\) 数,那么我们一定可以将这个数移给 \(B\),并且在 \(B\) 中一定不是 \(H\) 数。

因为它在 \(P\) 中不是 \(H\) 数,所以前面有比它大的,而比它大的数不是在 \(A\) 就一定在 \(B\)

推论:如果划分 \(A,B\) 都存在在 \(P\) 中不是 \(H\) 数的 \(H\) 数,那么可以 \(A,B\) 同时向对方移一个这样的数,两个序列 \(H\) 数的差不变,一直到一个序列不存在这样的数。

所以我们在判定 \(p\) 后面是否有合法划分时,可以固定 \(A,B\) 中的一个序列全部是 \(P\) 中的 \(H\) 数。

假设固定 \(A\),设 \(p\) 后面有 \(S\)\(H\) 数,设 \(B\) 中有 \(x\)\(P\) 中的 \(H\) 数,和不是 \(P\) 中的 \(H\) 数的 \(H\) 数,那么推出 \(A\) 序列有 \(S - x\) 个元素。现在又 \(C_A-C_B = x + y - (S - x) \to C_A - C_B + S = 2x + y\),所以我们把 \(P\)\(H\) 数置为 \(2\),其余的权为 \(1\),就是求是否有权值为 \(C_A - C_B + S\) 的上升子序列。

固定权值不好求,但是我们发现如果有权值为 \(X\) 的合法子序列,一定有 \(X-2\) 的子序列。因为如果子序列存在两个即以上 \(1\) 就删掉两个,否则一定存在 \(2\) 可以删掉。所以我们只用对奇数和偶数分别求最大上升子序列。可以用线段树维护。

还是有点抽象,配合代码食用,时间复杂度 \(\mathcal{O}(N\log N)\)Submission #32157754 - AtCoder Grand Contest 028

AGC029F

给定 \(n-1\) 个点集,从每个集合中选两个点连边,构造一颗树。

对于树的性质,\(x\) 条边要使得 \(x + 1\) 个点连通。所以有解的必要条件是对于任意的边集 \(|S|\),有 \(|F(S)| \ge |S| + 1\),其中 \(F(S)\) 表示 \(S\) 中的边对应的集合的并集。

这样我们联想到 Hall 定理,所以我们猜测这条件就是充分条件。

考虑固定 \(1\) 为根结点,那么初始点集为 \(V = \{1\}\),初始边集为 \(E = \varnothing\)。那么如果每次选择一条边同时让点集和边集扩大 \(1\),那么就可以归纳得到答案。

由于有解的条件强于 Hall 的条件,所以如果有解,我们删掉点 \(1\) 后一定可以找到一个大小为 \(n - 1\) 的二分图匹配。其中一个点匹配一条边。每次我们从枚举一条二分图 \(x \leftrightarrow y\),其中 \(x \in V,y\notin E\),那么我们可以将 \(match(y)\)\(x\) 连边,扩大点集和边集,并且我们发现只要满足 \(|F(S)| \ge |S| + 1\),扩大后仍然满足条件。

AGC016E

\(N\) 只火鸡,依次有 \(M\) 个人,第 \(i\) 个人会在 \((x_i,y_i)\) 中选择,如果有火鸡就选择一只吃掉。问最后有多少对 \((i,j)\) 使得第 \(i\) 只和第 \(j\) 只火鸡可能同时存活。

妙妙题。我们如果让 \(i\) 最后存活,那么我们从后往前倒着考虑每个操作。首先将 \(i\) 加入集合 \(S\) 表示此时必须存活。如果是操作 \((i,x)\) 那么此时 \(x\) 一定存活,将 \(x\) 加入集合 \(S\)。因此对于每个操作 \((x,y)\) 如果恰有一个在集合中,就把另一个加入集合,如果两个都在集合中,说明 \(i\) 在任何情况下都不可存活。如果都不在集合中则说明无论如何选择都对 \(i\) 没有影响。

如果 \((i,j)\) 都要存活,那么可以让初始集合为 \(S = \{i,j\}\),但是这样复杂度 \(\mathcal{O}(N^2M)\)。而我们发现扩展 \(S\) 的过程类似于建树的结构,无解说明 \(S\) 中成环。那么我们可以对每个 \(i\) 建出 \(S_i\)\((i,j)\) 合法当且 \(S_i\)\(S_j\) 没有交。如果有交则存在 \(i \to x,j\to x\) 的路径,而在询问 \((i,j)\)\((i,j)\) 是相连的。这样复杂度是 \(\mathcal{O}(NM + N ^ 3/ \omega)\)

AGC020E

给定一个长度为 \(n\)\(0/1\) 串,可以将其中若干个 \(1\) 变成 \(0\)。我们可以将一个串的若干个相同连续子串压缩,如 \(0000 = (0\times 4) = (00\times 2)= ((0\times 2)\times 2)\)。求所有可能的串的可能的压缩方案之和。

先考虑不能将 \(1\) 变成 \(0\) 的方案,即串是固定的。那么这就是经典区间 DP,用 \(f_{l,r}\)\(g_{l,r}\) 分别表示区间 \([l,r]\) 的方案,和区间 \([l,r]\) 并且压缩串的开头和结尾是匹配的左右括号的方案。枚举循环节转移。

现在考虑能够变化,我们把状态变成 \(f_{n,S}\) 表示长度为 \(n\) 的串 \(S\) 的方案,我们枚举循环节 \(d|S\),转化为子问题 \(f_{d,T}\),其中 \(T\)\(S\)\(d\) 为循环节的 \(\frac{n}{d}\) 段的交。虽然看起来状态很多,但有用状态很少,直接写个记搜就能过。

AGC028F

给定 \(N\times N\) 的矩阵,每个元素是一个数或障碍。从每个格子出发可以向右或向下走。如果格子 \(X\) 能不经过障碍到达 \(Y\),产生两个格子中数的乘积的收益,问总收益。

首先我们想到的是直接 DFS 每个格子能到的点,这样复杂度是 \(\mathcal{O}(N^4)\)。由于每次只能移动到右下相邻格子,这让我们想到经典 DP 模型 \(f_{i,j} = f_{i + 1,j} \oplus f_{i, j + 1}\)

考虑计算 \(l_{i,j,k}\) 表示从 \((i,j)\) 出发,能到达第 \(k\) 行的左断点,同理 \(r_{i,j,k}\) 表示右端点。这可以直接 \(\mathcal{O}(N^3)\) 计算。但是 \((i,j)\) 能到达的点在第 \(k\) 行并不一定是连续的一段。同时我们观察到,在 \([l,r]\) 区间中不能到达的位置,在之后的起点中也一定不能到达,所以我们只用直接将这些数删掉即可。时间复杂度 \(\mathcal{O}(N^3)\)

AGC025E

给定 \(n\) 个点的树和 \(m\) 条路径。你需要将 \(m\) 条路径定向,使得覆盖的有向边数量最大。

很好的思维+代码题。

直接考虑归纳。我们将树固定一个根,每次抠出一个叶子结点 \(x\) 出来。如果没有从 \(x\) 出发的路径,就直接删掉。如果有一条 \((x,y)\) 的路径,那么无论方向如何,都不会影响到 \(x\) 到父亲这条边,我们将路径 \((x,y)\) 修改为 \((fa_x, y)\),并删除点 \(x\)

如果存在 \(\ge 2\) 条路径。我们任取两条 \((x,u),(x,v)\),让它们方向相反,就能使得 \((x,fa_x)\) 这条边两个方向都被覆盖。那么两条路径可以合并成 \((u,v)\)。然后删除点 \(x\) 做下去。

简单分析一下产生的新边数量是 \(\mathcal{O}(nm)\) 可以接受。最后我们再扫一遍 \(\mathcal{O}(nm)\) 算出总的覆盖边数。

思路很清晰,但是代码并不好写。代码核心思想大概是每个点开 vector 维护结构体 {op,id,a,b,x,y} 分别表示 修改前有关的原路径数量、编号、路径端点a、端点b、关联路径标号x,关联路径标号y。队列维护删除叶子顺序。最后递归还原原路径的方向。Submission #32273991 - AtCoder Grand Contest 025

AGC031D

给定初始两个排列 \(p,q\),定义变化 \(f(p,q) = a\),则有 \(a_{p_i} = q_i\),求 \(k\) 次变化后的排列。\(n\le 10^5,k\le 10^9\)

置换/线性代数。我们可以将排列当作一个置换来做。

定义置换的乘积运算 \(a = p \circ q\),则有 \(a_i = p_{q_i}\)。有结合律 \(a \circ b\circ c = a\circ(b\circ c)\),没有交换律。定义单位元 \(\epsilon\) 满足 \(\epsilon_i = i\),有 \(p \circ \epsilon = \epsilon \circ p = p\)。定义逆元 \(p^{-1}\) 为满足 \(p \circ p^{-1} = \epsilon\) 的置换。任意置换有逆元且有唯一的逆元。

以上这些性质和矩阵乘法非常类似,所以可以当作矩阵进行运算。

回到题目,有变化 \(f_{p_i} = q_i\),等价于 \(f \circ p = q\)。所以 \(f = q \circ p^{-1}\)。然后开始找规律,手算前面若干项。

\(f_1 = p,f_2 = q, f_3 = qp^{-1},\cdots,f_7 = (qp^{-1}q^{-1}p)p(p^{-1}qpq^{-1})\)

我们记 \(\omega = qp^{-1}q^{-1}p\),那么有 \(f_7 = \omega p\omega^{-1},f_8=\omega q \omega^{-1}\),然后我们计算 \(f_9\) 发现正好消掉一对 \(\omega\omega^{-1}\),得到 \(\omega qp^{-1}\omega^{-1}\),所以有 \(f_n = \omega f_{n - 6}\omega^{-1}\),直接快速幂即可。

AGC032C

给定一个简单无向连通图,问能否将边集划分成三个环,环上的点可以重复。

由于图是连通的,所以我们能划分成 \(x\) 个环,就一定能划分成 \(x - 1\) 个环。因此有解的必要条件是存在欧拉回路。可能合法的图每个点度数都是偶数。

我们观察一下求欧拉回路的过程,每次任意走一条出边就能保证有解。每到达一个点两次就能划分出环。所以如果存在点度数 \(\ge 6\) 就一定有解。

现在只剩下度数为 \(2/4\) 的点,度数为 \(2\) 的点一进一出,可以直接删掉并合并两条边。所以只用考虑度数为 \(4\) 的点。手算一下不难发现点数 \(\ge 3\) 一定有解。\(1\) 个点肯定无解。点数 \(=2\) 时只要存在自环就有解。

具体代码实现不用真正删点缩边,我们删除其中一个度数 \(=4\) 的点,判一下剩下的子图是否连通即可。

AGC031E

给定二维平面上 \(n\) 个点,选出若干个点使得权值和最大且满足 \(m\) 个条件。每个条件形如在直线上/下/左/右方最多选 \(b_i\) 个点,保证直线平行坐标轴。

数据范围很小,限制条件很复杂,所以优先考虑网络流。

我们将条件转化一下,比如横坐标 \(\le x\) 的点最多有 \(y\) 个,转化为横坐标第 \(y + 1\) 大的点,横坐标 \(> x\)。这样对一堆点的限制就转化为对一个点的性质。

所以我们枚举一下选出多少个点,然后建出对应的图跑费用流。

AGC032F

随机将 \([0,1)\) 分为 \(n\) 段,求 \(n\) 段与 \(\frac{1}{3}\) 最小的差的期望。

不可做题。可能(?)通过找规律做一做。答案是

\[Ans = \dfrac{1}{n}\sum\limits_{i = 1}^{n}\dfrac{1}{3^i(n - i + 1)} \]

不过有个挺优美的结论可以记一下。随机 \(n- 1\) 个点分成 \(n\) 段,最短的一段的期望长度是 \(\dfrac{1}{n^2}\),第 \(k\) 短的期望长度是 \(\dfrac{1}{n}\sum\limits_{i = 1}^k\dfrac{1}{n - i +1}\)

AGC032E

给定 \(2n\) 个在 \([0,m)\) 范围内的非负整数,将这些数分成 \(n\) 个二元组 \((x,y)\),使得 \((x + y)\bmod m\) 的最大值最小。

\((x+y)\bmod m\) 的值只可能是 \(x + y\)\(x + y - m\)。对于 \(x+y < m\) 的二元组之间连红线,$\ge m $ 的连蓝线,我们发现可以通过调整法将所有红线移到蓝线左边,且任意两条线不相交。

那么我们可以通过枚举红线和蓝线的断点简单做到 \(\mathcal{O}(N^2)\),简单观察一下发现红线越少答案越优,我们直接二分出最左边的断点即可。

AGC033D

给定一个 \(N\times M\)\(0/1\) 矩阵,一个矩阵中的数全部相同,则该矩阵的复杂度为 \(0\),否则我们将矩阵划分成两个非空子矩阵,矩阵的复杂度就是划分的两个子矩阵复杂度的较大值 \(+ 1\),从所有划分方案中选择最优的。问整个矩阵的复杂度。

直接按题意模拟状态数就达到 \(N^4\) 了,我们需要观察一些性质。

比如我们每次划分矩阵的中线,那么最多 \(\log\) 次就划分成 \(1\times 1\),所以答案是 \(\log\) 级别的。这样我们把答案变成状态,定义 \(f_{t,l,r,x}\) 表示答案为 \(t\),矩阵上下边界分别为 \(l,r\),左边界为 \(x\),右边界的最大值。直接二分转移是 \(\mathcal{O}(N^3\log ^2 )\),也可以用双指针去掉一个 \(\log\)

AGC010E

给定一个长度为 \(n\) 的序列 \(a\),小 B 每次可以选择两个相邻的互质的数交换,他会将序列操作成字典序最大的。小 A 先将 \(a\) 重排,使得被小 B 操作后的字典序最小。

我们先看小 B 会如何操作,如果 \(\gcd(a_i,a_j)> 1,(i < j)\),那么我们连一条有向边 \(i \to j\),小 B 会求出这个 DAG 的最大拓扑序。我们将队列换成优先队列即可。

反过来考虑小 A。图论建模。如果 \(\gcd(a_i,a_j)>1\),就连一条 \((i,j)\) 的无向边。问题转化为给每条无向边定向。如果只有一个连通块,显然从 \(1\) 开始,每次选最小的出边定向,并 DFS 下去。多个连通块独立做即可。这非常符合直接,但证明貌似非常困难(?)时间复杂度 \(\mathcal{O}(N^2)\)

AGC034E

给你一颗 \(n\) 个节点的树,某些结点上有棋子。可以进行若干次操作,每次操作可以将两颗距离至少为 \(2\) 的棋子向中间移动一步。问能否通过若干次操作使得所有的棋子都在一个点上,如果能,输出最小操作次数,如果不能,输出 \(-1\)

显然枚举结束时所有棋子所在点,将该点作为根,那么我们可以贪心操作,每次选择两个棋子让它们深度同时减一。

直接树形 DP,定义状态 \(g_x\) 表示子树 \(x\) 之内所有棋子到 \(x\) 的距离之和,\(f_x\) 表示子树内所有棋子贪心操作后,到 \(x\) 距离之和的最小值。\(g_x\) 转移非常简单。定义 \(s_x = \sum \limits_{y\in son(x)}g_y\),显然有 \(f_x = \max\{g_x\bmod 2,f_y - (s_x - g_y)\}\)。式子的含义是枚举 \(g_x\) 最大的子树,让它自己内部操作,不能操作完的用其它子树来填。

AGC034D

在一个二维坐标系内,点 \((RX_i,RY_i)\) 上有 \(RC_i\) 个红球,点 \((BX_i,BY_i)\) 上有 \(BC_i\) 个蓝球,且保证 \(\sum_{i=1}^{n}RC_i=\sum_{i=1}^{n}BC_i\)

现在要你将这些红球蓝球一一配对,配对的价值为两球所在点之间的曼哈顿距离,请你求出配对完它们的最大价值和。

关键信息:曼哈顿距离,求最大值。

曼哈顿距离有一个优美的性质,\(|x-X| + |y - Y| = \max\{(x+y) - (X+Y),(x-y)-(X-Y),(y-x)-(Y-X),(-x-y)-(-X-Y)\}\)

对曼哈顿距离求最大值等价于 \(\max\{\max\{\}\}\),可以直接去掉外面的绝对值。匹配问题,直接建图跑费用流即可,时间复杂度 \(\mathcal{O}(N^2\log N)\)

AGC034F

给定长度为 \(2^n\) 数组 \(a_0,a_1,\cdots,a_{2^n-1}\),初始一个数 \(x = 0\),每次以 \(\dfrac{a_i}{\sum a}\) 得概率另 \(x\leftarrow x \operatorname{xor} i\),对于每个 \(i \in [0, 2^n - 1]\)\(x\) 第一次变成 \(i\) 得期望步数。

我们记 \(E(S)\) 表示 \(x = S\) 得期望步数,初值 \(E(0) = 1\),然后有方程 \(E(S) = 1+\sum\limits_{T\subseteq S}E(S\operatorname{xor}T)P(T)\)

直接写成集合幂级数,其中集合乘法指异或。那么有 \(E = I + PE\),由于要满足 \(E(0) = 0\),所以要加入一个修正常数,即 \(E = I + PE + C\),移项得 \(E = \dfrac{I+C}{1-P}\),由于 \(C\) 只有 \(C(0)\neq 0\),所以我们解出 \(C(0) = c\),有 \([x^{\varnothing}](I+C) = c + 2^n = [x^\varnothing](E-EP) = 0\),所以 \(c = -2^n\)

同时我们观察到 \([x^\varnothing](1-P) = 0\),所以最终求出得 \(E(0)\) 会有 \(/0\) 这样得问题,结果是错误的。不过幸运的是最终求出来的其余数相对的差是对的,我们反推 \(E(0)\) 即可。

AGC035D

给定长度为 \(N\) 的序列,每次选择一个 \(i\) 满足 \(1<i<N\),然后让 \(a_{i-1}\)\(a_{i + 1}\) 加上 \(a_i\),并删掉 \(a_i\),最后剩一个数。求这个数的最小值。

逆向思考,我们考虑每次加入一个数,然后对每个数算贡献。记函数 calc(l, r, p, q) 表示区间 \((l,r)\)\(a_l\) 被算了 \(p\) 次,\(a_r\) 被算了 \(q\) 次的最小贡献。枚举 \(l<i<r\),然后对 calc(l, i, p, p + q) + calc(i, r, p + q, q) + a[i] * (p + q)\(\min\) 即可。简单算一下复杂度 \(T(2) = 1, T(N) = \sum\limits_{i = 2} ^N T(i) + T(N - i + 1)\)。解出来发现 \(T(N)=3^{N-2}\) ,可以通过 \(N = 18\)

AGC035E

给定 \(N,K,P\),开始黑板上有 \([-\inf,\inf]\) 范围内的整数,每次可以选择擦掉一个数 \(x\in[1, N]\),并把 \(x-2,x+K\) 写上黑板,问最后黑板上留下的数有多少可能,对 \(P\) 取模。

留下的数是无穷多个,我们直接计数擦掉的数有多少可能。

观察一下发现,如果要擦掉 \(x,x-2\),那么一定要先擦掉 \(x\),否则在擦掉 \(x\) 时又会重新写上 \(x - 2\)。对于 \(x,x+K\) 同理。这样就形成了一个拓扑结构,我们要选择一些点出来使得不能成环。图的形态很特殊,可以直接 DP 出来,注意对于 \(K\) 为奇数和偶数要分开讨论。

AGC035F

给定 \(n\times m\) 的全 \(0\) 网格,先将每行最左边的若干个格子 \(+1\),再把每列最上面的若干个格子 \(+1\),问最后的网格有多少种可能。

网格最后只有 \(0/1/2\),先思考什么情况下两种不同的操作方案会得到相同的网格。

我们发现对于 \(0/2\) 的格子肯定不存在重复。对于一行和一列连接且不相交时,方案会重复,如下图。

0 0 1 0
1 1 1 0
0 0 0 0

第二行和第三列选两个格子,和第二行选三个,第三列选一个本质是相同的。那么我们钦定只统计第一种情况。容斥掉第二种情况。由于一行不可能和超过一列同时产生冲突,所以可以看成是行和列的匹配方案,枚举匹配数得到答案。

\[Ans = \sum\limits_{i = 0} ^ {n}(-1)^i\binom{n}{i}\binom{m}{i}(n + 1) ^ {m - i + 1}(m + 1)^{n-i+1}i! \]

AGC036D

初始一张 \(N\) 个点的图,对于每个 \(i\in[1,N)\) 有边权为 \(0\) 的边 \(i\to i + 1\),对于所有 \(1\le i<j\le N\) 有边权为 \(-1\) 的边 \(i\to j\),和边权为 \(1\) 的边 \(j\to i\),删除 \(x\to y\) 的边需要花费 \(A_{x,y}\) 的代价。问最少花费多少代价使得图没有负环。

这里有一个很巧妙的模型转化。如果图不存在负环,说明原图构成的差分约束系统有解。也就是我们把每个点看成一个变量,每条边看成一个不等式。有 \(x_i\ge x_{i + 1}\),作差分 \(u_i = x_i-x_{i + 1}\),有 \(u_i\ge 0\)

那么对于 \(i\to j\) 的边,有 \(\sum\limits_{k=i}^{j-1}u_i \ge 1\),同理如果 \(j\to i\) 则是 \(\le 1\)。因此 \(u_i\in\{0,1\}\),我们直接 DP,\(f_{i,j}\) 表示最后两个 \(1\) 位于 \(i,j\) 的答案,枚举 \(k\) 转移 \(f_{j,k}\to f_{i,j}\) 即可。

AGC036E

给定长度为 \(n\) 的 ABC 串,构造一个最长的子序列,满足 A,B,C 的出现次数相同,且子序列相邻两项不相同。

奇妙的贪心构造题。显然对于原串相同字符的极长段,可以缩成一个字符。

\(c_A,c_B,c_C\) 表示三种字符的出现次数。我们钦定 \(c_A\le c_B\le c_C\) ,肯定先贪心删去 \(C\),如果一个 \(C\) 相邻两项不同,就直接删去。

如果没有可删后还是 \(c_A\le c_B< c_C\),那么我们肯定选择删相邻的 \(AC\)\(CA\),这样一定会得到 \(c_A\le c_B=c_C\) 的情况,最后删除相邻的 \(BC\)\(CB\) 即可。

AGC037D

给定 \(n\times m\) 的矩阵,元素是 \(1\sim nm\) 的排列。现在要将矩阵通过三步排序,第一步奖每一行的元素任意排列得到 \(B\),第二步奖每一列的元素任意排列得到 \(C\),最后一步还原。先构造方案,输出 \(B,C\)

我们先把每个元素重标号为它的最终行数,那么矩阵中对于 \(1\sim n\) 各有 \(m\) 个数。我们要将这些数分组,使得每一组恰好有 \(1\sim n\) 个元素,且一组中不存在两个元素在同一行。

那么这就是经典的匹配问题,直接二分图/网络流即可。

AGC037E

初始一个长度为 \(n\) 的字符串 \(s\),进行 \(k\) 次操作,每次操作将 \(s\) 的反串接在 \(s\) 后面,并保留一个长度为 \(n\) 的子串,求 \(k\) 次操作后字典序最小的串。

这个题如果用传统的思路,按位考虑,并不能取得好的进展。

我们可以换一个思路,我们考虑 \(s\) 中最小的字符去向。如果 \(k = 1\),那么我们可以暴力求出最小的串。同时我们发现如果能求出串 \(a\),就一定能求出 \(a\) 的反串。所以我们把 \(k=1\) 时的串记为 \(t\),那么 \(t_1\) 一定是最小的,我们求出最大的 \(i\) 使得 \(t_{1\sim i}\) 相同,那么之后没一次操作,都能使这一段的长度翻倍。不难证明这就是最优决策。

AGC038E

给定一个随机数生成器,给定参数 \(A_1\sim A_n\),每次以 \(\dfrac{A_i}{\sum A}\) 的概率生成 \(A_i\),如果存在 \(i\) 被生成了 \(B_i\) 次就结束。问期望次数。

难度很高的数数题。

相当于求所有 \(i\) 中出现 \(B_i\) 次的时间的 \(\max\),考虑 \(\min-\max\) 容斥,相当于 \(\sum\limits_{T\subseteq S}(-1)^{|T| + 1}E(\min)\)

那么现在考虑对于一个 \(T\),怎么求 \(E(\min)\),经典结论,\(\dfrac{\sum_{x\in T}A_x}{\sum A}\) 的概率取到 \(T\) 中的数,那么取到的期望次数就是倒数。处理一下可以忽略 \(T\) 外元素的影响。

结论:某次达到 \(B_i\) 的期望,等价于所有没有达到 \(B_i\) 的状态的概率之和。

直接组合意义,因为持续时间和结束时间是相等的。

这样我们对 \(T\) 中每个元素 \(x\),枚举状态中的 \(C_x<B_x\),这个状态的概率是 \(\dfrac{(\sum C)!}{\prod C_x!}\prod(\dfrac{A_x}{\sum A_x})^{C_x}\)

拆式子,可以得到 \((\sum C_x)!(\sum A_x)^{-\sum C_x}\prod \dfrac{A_x ^ {C_x}}{C_x!}\)

数据范围的值域很小,所以我们直接 DP ,状态 \(f_{i,\sum C_x,\sum A_x}\) 表示前 \(i\) 个数所有子集的答案。

AGC038F

给定两个长度为 \(N\) 的排列 \(P,Q\),求两个排列 \(A,B\) 满足 \(A_i = P_i\)\(A_i=i\),且 \(B_i = P_i\)\(B_i=i\),使得 \(A_i\neq B_i\)\(i\) 个数最少。

先将条件转化一下。我们将排列看成若干个置换环,不难发现对于每个置换环,要么不变,要么环上每个元素都 \(=i\)

那么我们对每个 \(i\) 依次考虑过去。如果 \(P_i = Q_i=i\),那么一定不产生贡献。如果 \(P_i\neq i,Q_i = i\),那么只有 \(P_i\) 环不变时产生贡献。对于 \(P_i = i,Q_i\neq i\) 同理。对于 \(P_i = Q_i \neq i\) 的情况,两个环都变或都不变时不产生贡献。否则对于 \(P_i \neq i,Q_i\neq i\) 的情况,只有两个环都变时不产生贡献。

接下来就是最小割模型。我们将每个环看成图中一个点,如果 \(P\) 中的环与 \(S\) 连通,说明环不变,如果 \(Q\) 中的环与 \(T\) 连通,说明环不变。然后按照上述讨论连边即可。由于是二分图所以复杂度是 \(\mathcal{O}(N\sqrt N)\)

AGC018F

给定两个树,标号均是 \(1\sim n\),现在需要给每个 \(i\in[1, n]\) 固定一个权值,使得两棵树均满足任意结点子树和的绝对值等于 \(1\)

我们先观察以下,由于每个点的子树和绝对值都是 \(1\),那么考虑从叶子向上推,如果当前结点有 \(s\) 个儿子,如果 \(s\) 为奇数,那么当前结点为偶数,同理 \(s\) 为偶数则当前结点为奇数。如果两棵树上的奇偶性不同,显然无解。

有关度数的奇偶性,我们容易想到欧拉回路。我们建一个虚点同时连接两棵树的根,那么整个图就连通了。然后对于两个奇点,在它们之间连一条边,这样的边我们称为附加边。最后求欧拉回路。

由于原图是树,不存在环,所以从任意点出发,想要回到该点,必须先走到另一棵树再回来,来回之间经过的附加边。所以如果附加边从 \(A\)\(B\),则该点赋值为 \(1\),否则赋值为 \(-1\)

posted @ 2022-04-20 10:49  7KByte  阅读(727)  评论(0编辑  收藏  举报