2023.01.16 题目选讲 学习笔记

讲课人:张隽恺。

WC2023 Day4 上午的课。

1.P8493 [IOI2022] 数字电路

假设一个点有 \(x\) 个儿子取值为 \(1\)\(y\) 个儿子取值为 \(0\),则它有 \(x\) 种选择参数的方式使得其取值为 \(1\)\(y\) 种选择参数的方式使得其取值为 \(0\)。这等价于给一个点选择一个儿子,该点的权值等于该儿子的权值。那么根的取值也仅由某个儿子决定。

\(f_i\) 表示根节点的权值由第 \(i\) 个叶子决定的方案数,则 \(f_i\) 等于除去第 \(i\) 个叶子到根路径上的非叶节点,其余非叶节点儿子数的乘积。由于模数不是逆元,因此应当用换根 dp 求出所有 \(f_i\)。再设 \(v_i\) 表示第 \(i\) 个叶子的权值,则答案为 \(\sum_{i=1}^m v_if_i\),可以用线段树维护。

时间复杂度 \(O(n+m+q\log m)\),空间复杂度 \(O(n+m)\)

2.Gym104128C Fabulous Fungus Frenzy

假设没有操作次数限制,那么用一个大小为 \(x\times y\) 的模板覆盖相当于从矩阵中任意选择 \(xy\) 个元素并替换成模板中的 \(xy\) 个元素。考虑倒着操作,每次在矩阵中选择 \(xy\) 个元素和模板匹配,匹配完后这些元素全都变成通配符,通配符可以和任意字母匹配,最后要判断最终得到的矩阵能否和初始矩阵匹配。显然 \(xy\) 个元素不全为通配符才是有意义的,这样每匹配一次通配符数量至少加 \(1\),最多匹配 \(nm\) 次;每次匹配最坏要移动 \(nm\) 个元素,移动一个元素最坏要 \(n+m\) 次,所以最坏操作次数是 \(n^2m^2(n+m)\) 的。

一个优化是,在第一次使用某个模板后,模板内的元素全都变成了通配符,因此我们可以接着把其它不是通配符但能和该模板匹配的元素移到该模板覆盖的范围内,并且新移进来的元素在下一次覆盖后都会变成通配符。

因此操作次数降为了 \(knm(n+m)+nm(n+m)\)。算上最后把所有元素归位的 \(nm(n+m)\) 次操作,\(1\) 操作的总数不超过 \(knm(n+m)+2nm(n+m)=3.52\times10^5\)

3.P8491 [IOI2022] 囚徒挑战

一种做法是直接用 \(x\) 表示 \(A\),如果进去的人看到 \(x=0\) 则看 \(A\) 并把 \(x\) 改为 \(A\),否则看 \(B\)。此时 \(lim=n=5000\)

优化:如果看到 \(x\) 则表示当前在比较 \(A,B\) 二进制下从高往低数第 \(\lfloor\frac{x}{3}\rfloor+1\) 位(从低往高数第 \(\lceil\log_2 n\rceil-\lfloor\frac{x}{3}\rfloor\) 位)。如果 \(x=3i\) 则看 \(A\) 二进制下从高往低数第 \(i+1\) 位并根据该位的取值将 \(x\) 改成 \(3i+1\)\(3i+2\);如果 \(x=3i+1\)\(3i+2\) 则看 \(B\) 二进制下从高往低数第 \(i+1\) 位,若仍不能比较出大小,则将 \(x\) 改成 \(3(i+1)\)。这么做 \(lim=3\lceil\log_2 n\rceil-1=38\)

考虑用不同的进制,比如 \(4^5\times5\ge n\),那么通过用最高 \(5\)\(4\) 进制最低位 \(5\) 进制可以做到 \(lim=(4+1)\times5+(5+1)-1=30\)

上述过程中只有看到 \(A\) 的人传递了信息而看到 \(B\) 的人没有传递信息,所以不优,考虑让看到 \(B\) 的人也传递信息:如果 \(x=0\) 则看 \(A\) 并根据 \(A\) 二进制下的最高位把 \(x\) 改成 \(1\)\(2\);如果 \(x=1\)\(2\) 则看 \(B\) ,若不能比较出大小则根据 \(B\) 二进制下的次高位把 \(x\) 改成 \(3\)\(4\);如果 \(x=3\)\(4\) 则看 \(A\) ,若不能比较出大小则根据 \(A\) 二进制下的第三高位把 \(x\) 改成 \(5\)\(6\),以此类推。这样 \(lim=2\lceil\log_2 n\rceil=26\)

换用不同的进制,比如 \(3^8\ge 5000\),则可做到 \(lim=3\times8=24\)

在花费 \(26\) 次的做法中,其实一个人看完二进制最低位不需要再额外花 \(2\) 个数记录二进制最低位是什么,而可以直接确定 \(A,B\) 的大小关系,所以可以优化到 \(lim=2\lceil\log_2 n\rceil-2=24\)

同理,在 \(26\) 次做法的基础上换用不同的进制的做法,如果最低位是 \(B(B\ge2)\) 进制的并且看到最低位是 \(0\)\(B-1\),则可直接确定 \(A,B\) 的大小关系,也能少计 \(2\) 个数,可做到 \(lim=3\times8-2=22\)

考虑上述做法和优化的本质:初始时 \(A,B\) 的取值都在 \([1,n]\) 内,假设你现在已经知道 \(A,B\) 的取值都在 \([l,r]\) 内,并且看 \(A\)\(B\) 看到的数是 \(l\)\(r\),那么就可以直接确定两者的大小关系。也就是说,如果你能在 \(lim=x\) 时比较出 \(A,B\) 都在长度为 \(y\) 的区间内时两者的大小关系,那么你也能在 \(lim=x+k\) 时比较出 \(A,B\) 都在长度为 \(ky+2\) 的区间内时两者的大小关系。初始时 \(lim=0\)\(y=2\),dp 可以发现 \(lim=20\) 时从低往高 \(k\) 依次取 \(1,2,2,3,3,3,3,3\)\(y=5588\) 取到最大值,且 \(y>n\),因此也得到了方案。

4.AT_codefestival_2016_final_j Neue Spiel

推入操作等价于在推入的行或列的推入方向上找到第一个空位,并把方块放在该空位上。于是每个格子的方块只能来自其所在行的左右或所在列的上下。

有解的一个必要条件是存在一种方案,每个格子和四个推入方向之一匹配,使得每个推入方向匹配的格子数恰为该推入方向对应的 \(a\) 值。这可以用网络流 \(O(n^3)\) 判断无解或求出一组解。

如果有解,那么一个限制条件是一个格上的方块推入的时间比从它推入方向的第一个格子到它之前的所有格子上的方块的推入时间都要更迟。如果 \(x\) 上的方块推入时间要比 \(y\) 迟,那么从 \(x\)\(y\) 连一条有向边。如果连边得到的有向图无环,那么就可以拓扑排序构造方案。现在问题是怎样才能使得得到的图无环。

对于一个环,设环上的格子编号依次为 \(a_1,a_2,\cdots,a_k\),考虑让 \(a_i\) 匹配的推入方向变成 \(a_{(i+k-2)\bmod k+1}\) 原先匹配的推入方向(如下图),可以发现这个环就被消掉了,而且匹配方案仍然合法!并且,设 \(d\) 表示每个格子上的方块与其推入方向的第一个格子的距离之和,那么经过这个变换后 \(d\) 减小了环长,于是 \(d\) 最小的匹配方案一定不存在环!

现在有两种解决方案:1. 不断消环直至无环。2. 求出 \(d\) 最小的匹配。两者直接做都是 \(O(n^4)\sim O(n^5)\) 的,据说都可以优化到 \(O(n^3)\),这里讲讲前者如何优化。

考虑我们得到的图中的所有边,如果找到一个环了一些边会被消去,但是原来不存在的边现在也一定不存在!也就是说一条边只可能从存在变成不存在,而不可能从不存在变成存在。于是我们考虑 dfs 找环,如果从某个点出发能到达的点中都没有环,那么之后也一定不会有环,于是之后就可以不再访问这个点了。如果 dfs 的过程中找到了环,消去该环,并回溯到这个环中最先被 dfs 到的点,继续消环的过程(注意要当前弧优化)。

考虑每次遍历一条 \(x\rightarrow y\) 的边时,在回溯时计算该边对时间复杂度的贡献:要么是找到一个长为 \(l\) 的环,\(d\) 减小 \(l\),花费 \(O(l)\) 的时间;要么是没找到环,且之后能遍历的点数少 \(1\),花费 \(O(n)\) 的时间(一个点的出边有 \(O(n)\) 条)。而 \(d\) 一开始是不超过 \(O(n^3)\) 的,一开始能遍历的点数是 \(O(n^2)\) 的,所以这部分的时间复杂度也不超过 \(O(n^3)\)

总时间复杂度 \(O(n^3)\),空间复杂度 \(O(n^2)\)

5.AT_agc043_e [AGC043E] Topology

首先我们用形式化一些的语言来描述一下这条闭合曲线。记纵坐标 \(\lt\frac{1}{2}\) 的部分为下部,纵坐标 \(\gt\frac{1}{2}\) 的部分为上部。记操作 \(i_0\) 表示绳子从下部开始沿顺时针方向绕过 \(i\) 并回到下部,操作 \(i_1\) 表示绳子从下部开始沿逆时针方向绕过 \(i\) 并回到下部。那么任何曲线都可以表示成若干操作组成的环。

如果只保留 \(S\) 中的点,那么相当于原曲线只保留 \(S\) 中的元素对应的操作。

考虑能连续形变到 \(y<0\) 的曲线应满足什么性质,可以发现,如果存在相邻的 \(i_0,i_1\),就可以同时把这对 \(i_0,i_1\) 删去,如果能删空就说明曲线可以连续形变到 \(y<0\)。并且如果考虑从初始为空的曲线开始,不断往曲线中添加一些操作使得该曲线仍能连续形变到 \(y<0\),可以发现添加进去的操作一定也只能是在某个位置插入一对 \(i_0,i_1\)。所以,曲线能连续形变到 \(y<0\) 当且仅当不断删去相邻的 \(i_0,i_1\) 能把曲线删空。

如果对于一个状态 \(S\) 满足 \(f_S=0\),有任意 \(i\notin S\) 都有 \(f_{S\cup\{i\}}=0\),因为已有 \(S\) 中的点时曲线取不出来,再加入一个点肯定更取不出来。所以我们可以把存在 \(f_S=0,i\notin S,f_{S\cup\{i\}}=1\) 的无解情况先判掉。下面我们说明其余情况都一定有解。

我们考虑如果一个状态 \(S\) 满足 \(f_S=0\),且存在 \(i\in S\)\(f_{S\setminus\{i\}}=0\),那么我们其实不需考虑 \(f_S=0\) 的限制,因为 \(f_{S\setminus\{i\}}=0\) 可以直接推出 \(f_S=0\)。所以现在只需考虑所有的状态 \(S\),满足 \(f_S=0\),且对于任意 \(i\in S\)\(f_{S\setminus\{i\}}=1\),即只保留 \(S\) 中的元素时曲线取不出来,但在 \(S\) 中任意删去一个元素后曲线都取得出来。

考虑如果只有一个需要被考虑的状态,即 \(f_S=[S\neq\{1,\cdots,n\}]\) 时该怎么构造。

\(x_1,\cdots,\cdots x_n\) 表示 \(n\) 根柱子。

\(n=1\) 时:\((x_1)_0\)

\(n=2\) 时:\((x_1)_0(x_2)_0(x_1)_1(x_2)_1\)

归纳构造:已知 \(n-1\) 时的方案 \(S_{n-1}\),则令 \(n\) 时的方案 \(S_n=S_{n-1}(x_n)_0\overline{S_{n-1}}(x_n)_1\),其中 \(\overline{S}\) 表示把 \(S\) 中的方案翻转,并且 \(0,1\) 取反。首先可以发现 \(S_n\) 是不可能消空的。其次如果删了 \(x_1\sim x_{n-1}\) 中的任意一个,那么 \(S_{n-1}\)\(\overline{S_{n-1}}\) 都可以被消空,最后 \(S_n\) 也能被消空;如果删了 \(x_n\),那么相当于只剩下曲线 \(S_{n-1}\overline{S_{n-1}}\),每次可以消除最中间的两个。这就完成了单个状态的构造。

现在考虑如果有多个状态怎么办,注意此时我们并不能将它们直接简单地拼起来,因为拼起来后虽然每个状态对应的方案内部无法消除,但是相邻两个状态对应的方案可能可以互相消除。实际上,如果把每个集合 \(S\) 内部的数从小到大排序,再按照上述的归纳方法来构造,得到的方案就可以直接拼起来。原因在于,上述方法构造出来的序列会使得第一个操作对应的元素是序列内最小,最后一个操作对应的元素是序列内最大,且相邻两个操作跨过的元素不相同。那么相邻两个状态对应的方案最多只会互相消除一次,之后两边的操作对应的元素就不同了。

根据操作次数的递推式不难发现,状态 \(S\) 的操作次数约为 \(O(2^{|S|}n)\),因此总次数不超过 \(O(\sum_{S\subseteq\{1,\cdots,n\}}2^{|S|}n)=O(3^nn)\)

6.P8999 [CEOI2022] Drawing

先考虑一个暴力做法:在树上任取一点为根,在所有点的凸包上任取一点对应根,以该点为原点将其余点极角排序,把其余点划分成极角排序上连续的若干段,每一段对应根的一棵子树,每一棵子树的根是子树内唯一与上一层的根相邻的点,每一段内对应根的点是以上一层的根为原点极角排序后角度最小的点,重复上述过程即可。如果用 nth_element 实现划分,由于最多会划分 \(n\) 层,每层复杂度不超过 \(O(n)\),所以总复杂度是 \(O(n^2)\) 的。这也说明了题目一定有解。

现在我们希望划分的层数少一些,很容易想到每次根不应该随便取,而应该取重心。但是在第一层取完重心后,如果第二层又取了子树内的重心,子树内的重心和上一层的重心在树上不一定有边直接相连。不过我们还是取极角排序上角度最小的点作为子树内的重心,称上一层的重心为 \(u\),这一层的重心为 \(v\),现在我们尝试确定 \(u\)\(v\) 在树上路径上的点依次对应平面上的哪些点(如下图左)。

我们现在知道的条件是,如果作直线 \(uv\),那么所有点都在这条直线的一侧(如上图右)。

考虑二分,即先找到 \(u\)\(v\) 在树上路径上的中点 \(x\) 在平面上对应哪个点。在 \(x\) 确定后,根据直线 \(ux,vx\),平面被分成了四部分。如下图所示我们把四部分称为 \(A,B,C,D\)(注意这四个部分都是无界的)。设 \(x\) 的链外子树为 \(a\)\(u\rightarrow x\) 路径上(不含 \(x\))的所有链外子树为 \(b\)\(v\rightarrow x\) 路径上(不含 \(x\))的所有链外子树为 \(c\)。我们希望 \(D\) 内部没有点,\(a,b,c\) 对应的点在以 \(x\) 为原点极角排序后连续,且 \(a,b,c\) 对应的点每部分内最大极角减最小极角小等于 \(180^{\circ}\)。对于 \(|b|,|c|\) 的限制就是 \(|b|\le|A|+|B|,c\le|A|+|C|\),对于 \(|a|\) 的限制貌似比较难描述,但是我们加强一下限制,可以描述为 \(|c|\ge|C|\)

现在我们来逐条满足上述限制。首先过 \(u\) 作一条直线,使得直线不包含 \(v\) 的一侧恰有 \(|b|\) 个点;同样地过 \(v\) 作一条直线,使得直线不包含 \(u\) 的一侧恰有 \(|c|\) 个点。我们根据这两条直线再把平面分成 \(e,f,g,h\) 四个部分,由于 \(|g|+|e|=|b|,|e|+|h|=|c|\),所以 \(|g|+|e|+|h|\le|b|+|c|\),而 \(|g|+|e|+|h|+|f|=|a|+|b|+|c|+1\),所以 \(f\) 内部必然有点。

\(u\) 为原点,取 \(f\) 内部极角序最大的点 \(x\)(即 \(xuv\) 夹角最小,或者说 \(x\) 在图中相对比较靠上),那么直线 \(ux\) 下方点数 \(\ge|b|\),即 \(|A|+|B|\ge|b|\);直线 \(vx\) 下方点数 \(\ge|c|\),即 \(|A|+|C|\ge|c|\);红色部分没有点,蓝色部分内点数 \(\le|h|+|e|=|c|\),故 \(|C|\le|c|\)。我们发现,上述条件已经全部满足了!

我们上述过程是先点分,每层点分内部还有个二分,所以每个点可能会出现在 \(O(\log^2 n)\) 层内。但实际上二分的时候按照链外子树大小进行二分(类似全局平衡二叉树),就可以使每个点出现的层数是 \(O(\log n)\) 的。

总时间复杂度 \(O(n\log n)\),空间复杂度 \(O(n)\)

7.P8276 [USACO22OPEN] Hoof and Brain P

首先如果有棋子在出度为 \(0\) 的点上,一定是后手输,所以如果一开始没有棋子在出度为 \(0\) 的点上,后手也不会把棋子移到出度为 \(0\) 的点上,把出度为 \(0\) 的点删去不影响博弈胜负。

删去所有出度为 \(0\) 的点后,考虑出度为 \(1\) 的点 \(u\),设其有出边 \(u\rightarrow v\)。如果先手能在 \(u\) 赢,那么先手可以让两个棋子都多移动一步就也能在 \(v\) 赢;如果有棋子在 \(u\),那么先手一定能让后手把棋子移到 \(v\);如果 \(u,v\) 同时有棋子,那么先手选择 \(u\) 后手就输了,所以后手不会让 \(u,v\) 同时有棋子。所以我们可以让 \(u\) 的所有入边都指向 \(v\)(要删去重边),然后删去 \(u\)(或者说把 \(u,v\) 合并成一个点),这样不影响博弈胜负。(注意到在删的过程进行时可能会产生自环,如果存在满足上述情况的 \(u\),唯一出边是自环,那么经过上述操作后什么都不会发生,要特判唯一出边为自环的点不进行此操作)

现在所有点要么出度 \(\ge2\),要么出度 \(=1\) 且唯一出边是自环,并且两个棋子在不同点上,此时一定是后手赢:对于每次先手选中的棋子,如果所在点出度 \(=1\),那么可以保持不动;如果所在点出度 \(\ge2\),则指向 \(\ge2\) 个点中至少有一个点是能去的。

如何快速维护上述过程?首先删完所有出度为 \(0\) 的点。一种想法是,用 unordered_set 维护每个点的入边的起点的集合,以及每个点的出度大小。把出度为 \(1\) 的点加入队列,每次从队列中取出一个点,判断出边是否是自环,如果是则忽略该点,如果不是则启发式合并,并往队列中加入新的出度变为 \(1\) 的点。另一种想法是把上述想法的 unordered_set 换成动态开点线段树,把启发式合并换成线段树合并。

时间复杂度 \(O(n+q+m\log n)\),空间复杂度 \(O(m)\)\(O(m\log n)\)

8.P8426 [JOI Open 2022] 放学路(School Road)

首先跑出最短路图,要找一条从 \(1\)\(n\) 的长度大于 \(L\) 的路径有两种可能,一种是经过了最短路图外的边,一种是只经过最短路图上的边。

对于前者,只要经过一条最短路图外的边那么该路径长度就一定 \(>L\),我们只需判断每条最短路图外的边是否可以被经过。连边 \((1,n)\),把 \(1,n\) 所在的点双拎出来,由 做题笔记-2022.05.12 CF487E Tourists 的推论可知 \(1\rightarrow n\) 的简单路径能经过的边有且仅有与 \(1,n\) 在同一个点双中的边,这是好判断的。

对于后者,现在问题可以被转化为,给定一张 DAG(最短路图),\(1\) 只有出度,\(n\) 只有入度,每条边有方向。现在把图中边的定向取消,问能否找到一条从 \(1\)\(n\) 的简单路径使得经过的边中至少有一条边的经过方向与其在 DAG 中的定向不同。

我们还是同之前一样连边 \((1,n)\),并只保留 \(1,n\) 所在的点双(\((1,n)\) 这条边并不是真的连了,只是为了找点双用)。根据 做题笔记-2022.05.12 CF487E Tourists 的结论可知在剩下的点中,任意点 \(u\) 满足 \(u\ne1\)\(u\ne n\) 都存在一条 \(1\rightarrow u\rightarrow n\) 的简单路径。

对于 \(1,n\) 外被保留的点,如果有全是入度或全是出度的点 \(x\),那么选择路径 \(1\rightarrow x\rightarrow n\) 即可。

如果有点 \(x\) 入度和出度都恰为 \(1\),设入边为 \(a\rightarrow x\),出边为 \(x\rightarrow b\),则可删去这两条边和点 \(x\),连接 \(a\rightarrow b\),答案不变。

如果有重边,删去重边答案不会变。

经过上述操作后,剩余的点中除了 \(1,n\) 外,度数一定都大等于 \(3\)。一个结论是,如果这时候只剩下 \(1,n\) 两个点了,那么就不存在这样的路径,否则一定存在。

前者是好理解的。对于后者,我们任取一条 \(1\rightarrow n\) 的经过点数最多的路径(注意是 DAG,下称为最长路),显然 \(1,n\) 在最长路上不相邻。考虑最长路上 \(1\) 下一个点 \(u\),由于 \(u\) 的度数大等于 \(3\),所以 \(u\) 一定存在一条不在最长路上的出边,且沿着该边一定能延伸出一条路径回到最长路上的点 \(v\)(注意是在无向图上延伸),\(v\) 在最长路上在 \(u\) 之后。如果 \(u\)\(v\) 这条路径上的边的方向不全部顺向,那就可以选 \(1\rightarrow u\rightarrow v\rightarrow n\)。否则,\(u\)\(v\) 路径上的边的方向全部顺向,由于选的是最长路并且已经去掉了重边,所以 \(u,v\) 在最长路上不相邻。考虑最长路上 \(u\) 下一个点 \(p\),由于 \(p\) 的度数大等于 \(3\),所以 \(p\) 一定存在一条不在最长路上的边(可能是出边也可能是入边),且沿着该边延伸出一条路径回到最长路上的点 \(q\)(注意是在无向图上延伸)。如果 \(p\)\(q\) 路径上的边方向不全相同,则是好做的,否则 \(p\)\(q\) 路径上的边方向全相同。如果 \(p\) 不在最长路上的边是入边,则 \(q\) 在最长路上在 \(p\) 之前,且不为 \(u\),所以 \(q\)\([1,u)\) 间。此时 \(q\)\(p\) 路径上的边的方向全部顺向,可以选 \(1\rightarrow q\rightarrow p\rightarrow u\rightarrow v\rightarrow n\)。如果 \(p\) 不在最长路上的边是出边,则 \(q\) 在最长路上在 \(p\) 之后。此时 \(p\)\(q\) 路径上的边的方向全部顺向,这时考虑 \(q\) 在最长路上是在 \((v,n]\) 间还是在 \((p,v]\) 间。如果是前者,可以选 \(1\rightarrow u\rightarrow v\rightarrow p\rightarrow q\rightarrow n\)。如果是后者,接下来我们把上述的 \((u,v)\) 换成 \((p,q)\) 继续重复上述过程。由于 \((u,v)\) 换成 \((p,q)\) 后它们在最长路上的距离减小了,所以最终一定会出现有解的情况。

时间复杂度 \(O(n+m\log n)\),空间复杂度 \(O(n+m)\)

9.P8495 [IOI2022] 千岛

如果某个点出度为 \(0\),则沿某条边到达该点后,要想从该点走出只能原路返回,这是不合法的,所以不会到达入度为 \(0\) 的点,可以不断删去入度为 \(0\) 的点。

如果起点 \(s\) 的出度为 \(1\),设从起点沿唯一出边出发后到达 \(u\),之后第一次回到起点时起点的出度还是 \(1\),且此时从起点不能再走出去了,所以回来的边也一定是 \((s,u)\) 这条边。这可以看作,把 \(s\) 删去,并把 \(u\) 设作新的起点,答案不变。

剩余情况,起点出度至少为 \(2\),其它点出度至少为 \(1\)

给起点外的每个点都任意选定一条出边,这样所有被选定的出边构成了内向基环树森林。可以看出,从起点任意选一条边出发,一直走直至碰到重复点为止,经过的图形是一个 \(\rho\) 形。我们在 \(\rho\) 形的环上恰好走一圈,然后原路返回起点,这时相当于 \(\rho\) 形环上的边全被反向了,其它边方向不变,称这个过程为 \(A\)。这时再选一条起点的出边,且异于 \(A\) 过程里的起点的出边,类似 \(A\) 过程走一个 \(\rho\) 再原路返回,称这个过程为 \(B\)。可以发现,\(ABAB\) 即为一组合法的构造。

最后构造出的序列长度不超过 \(4m\)。时间复杂度 \(O(n+m)\),空间复杂度 \(O(n+m)\)

posted @ 2023-05-15 21:33  18Michael  阅读(4)  评论(0编辑  收藏  举报