ARC187 做题记
A (Add and Swap)
题意
给定两个整数 \(N,K\) 与一个长度为 \(N\) 的数列 \(A=(A_1,\dots,A_N)\)。
问是否能对 \(A\) 执行不超过 \(500000\) 次以下的操作,使 \(A\) 变为单调不减数列:
- 选择一个 \(i\) 满足 \(1\le i<N\),将 \(A_{i+1}+k \to A_i\) 且 \(A_{i}\to A_{i+1}\),注意两种操作同时进行。
如果可以,请输出具体方案。
\(1\le N,K,A_i\le 50\)
题解
- 注意到连续操作两次 \(i\) 能让 \(A_i,A_{i+1}\) 同时 \(+k\)。
限制很宽,于是我们猜测绝大多数情况都是可以的。首先特判 \(N\le 2\)。
考虑搞一个类似归纳的东西,已知 \(A_1\sim A_{k-1}\) 排好序,接下来让 \(A_1\sim A_{k}\) 排好序。
当 \(k\neq n-1\) 时候,直接让 \(A_{k},A_{k+1}\) 同时 \(+k\) 即可。
于是 \(A_1\sim A_{n-1}\) 排好序了,接下来要把 \(A_n\) 也排进来。
由于要改变 \(A_{n-1}\) 与 \(A_n\) 的大小关系,我们要操作一次 \(n-1\) 让 \((A_{n-1},A_n)\to (A_n+k,A_{n-1})\)。
我们先让 \(A_{n-2},A_{n-1}\) 一直同时 \(+k\) 直到 \(A_{n-1}>A_n+k\),然后操作 \(n-1\)。
接着把 \(A_{n-1},A_n\) 同时一直 \(+k\) 直到 \(A_{n-2}<A_{n-1}\) 即可。
操作次数限制太宽了,随便满足。
B (Sum of CC)
题意
对于序列 \(A=(A_1,A_2,\cdots,A_N)\) ,定义 \(f(A)\) 如下:
-
图中包含 \(N\) 个点,编号 \(1\sim N\),初始没有边。对于每个满足 \(1\le i<j\le N\) 的二元组 \((i,j)\),如果 \(A_i\le A_j\),则在节点 \(i,j\) 之间连接一条双向边。
-
\(f(A)\) 是图中的连通块数量。
给定序列 \(B=(B_1,B_2,\cdots,B_N)\),每一项的值 \(1\le B_i\le M\) 或者 \(B_i=-1\)。
将 \(B\) 序列中的 \(-1\) 替换为 \(1\) 到 \(M\) 中的整数,有 \(M^q\) 种不同的序列 \(B'\),其中 \(q\) 是 \(B\) 序列中 \(-1\) 的数量。
求所有 \(B'\) 序列的 \(f(B')\) 之和 \(\bmod\ 998244353\)。
\(2\leq N \leq 2000\),\(1\leq M \leq 2000\)。
题解
和 CF1270H 一个套路。
根据结论:连通块一定是以区间形式呈现在该序列上的。
对于点 \(i, j\) \((i < j)\),若 \(a_i \le a_j\),那么对于 \(\forall k \in [i, j]\):
- 若 \(a_k \ge a_j\),\((i, k)\) 存在连边。
- 若 \(a_k < a_j\),\((k, j)\) 存在连边。
综上,\([i, j]\) 每个点互相连通。
此时对于一个序列,连通块数等于分割点数量加 \(1\)(分割点指将序列分成若干个区间中间那些点)。
考虑枚举这些分割点 \(i\),则此时要满足 \(\min\limits_{j \le i} b_j > \max\limits_{j > i} b_j\)。
记 \(f_j\) 表示当前位置 \(i\) 左边 \(\min\ge j\) 的方案数,\(p\) 为 \(i\) 前面有多少个 \(-1\),那么显然有 \(f_j = (m - j + 1)^p\)。
同理可以求出位置 \(i\) 右边 \(\max\le j\) 的方案数 \(g_j\),位置 \(i\) 的贡献就是 \(\sum\limits_{j=2}^{m} f_j \times g_{j-1}\)。
时间复杂度 \(\mathcal{O}(nm \log n)\)。
C (1 Loop Bubble Sort)
题意
对于长度为 \(N\) 的排列 \(P\),定义一次操作如下:
- 枚举正整数 \(i \in [1,n)\),若 \(P_i>P_{i+1}\),则交换 \(P_i\) 和 \(P_{i+1}\)。
现在告诉你对 \(P\) 执行一次操作之后的序列 \(Q\)。
若 \(Q_i \not =-1\) 则操作之后的序列的第 \(i\) 个数等于 \(Q_i\);否则,\(Q_i\) 可以取任意数。
求排列 \(P\) 的数量,对 \(998244353\) 取模。
\(N \leq 5000\),\(Q\) 中每种非 \(-1\) 的数最多出现一次。
题解
首先一个经典的结论是:一轮冒泡排序做的事,实际上是将序列按照每一个前缀最大值划分成若干个区间,并将每个区间的最大值(初始时在最前面)循环移位至区间末尾。
这个过程其实就可以设计 dp 了,考虑记录前缀最大值进行 dp。
我们预处理:
- \(pos_i\) 表示 \(Q\) 中值的位置,不存在则值为 \(0\)。
- \(num_i\) 表示 \(\le i\) 的数中有多少个未在 \(Q\) 中出现。
- \(pre_i\) 表示 \(1 \sim i\) 中 \(Q\) 上有多少个 \(-1\)。
设 \(f_{i,j}\) 表示考虑到 \(P\) 的前 \(i\) 个数,当前前缀最大值为 \(j\) 的方案数。下面考虑转移:
-
若 \(P_i = j\),也即当前位置是前缀最大值。
此时 \(j\) 会向后移动,也即需要满足 \(pos_j \ge i\) 或 \(pos_j = 0\)。
同时上一个前缀最大值会被放在 \(i-1\) 的位置。
设上一个前缀最大值为 \(k\),我们需要满足 \(Q_{i-1} = k\) 或 \(pos_k = 0\)。
对于满足条件的 \(k < j\),我们有 \(f_{i,j} \leftarrow f_{i-1,k}\)。
-
若 \(P_i < j\),则 \(P_i\) 会向前移动一位。继续根据 \(Q_i\) 的取值分类:
- 若 \(Q_{i-1} \neq -1\),则此时该位置只能填写 \(Q_{i-1}\),且之前一定没有填写过这个数(由于其 \(pos\) 已经确定,故无论是否作为前缀最大值,转移都不合法)。故我们有 \(f_{i,j} \leftarrow f_{i-1,j}\)。
- 若 \(Q_{i-1} = -1\),则该位置可以填未在 \(Q\) 中出现过、且之前的 \(-1\) 未被填过的小于 \(j\) 的数。此时,\(Q\) 中 \(i-1\) 之前的填在 \(-1\) 处的值一定小于 \(j\),故剩余可行的值还有 \(num_{j-1} - pre_{i-2}\) 个。故我们有 \(f_{i,j} \leftarrow f_{i-1,j} \times (num_{j-1} - pre_{i-2})\)。
使用前缀和优化掉第一种情况的枚举 \(k\) 的操作即可做到 \(\mathcal{O}(n^2)\)。
D (Many Easy Optimizations)
题意
定义序列 \(X\) 的价值为 \(X\) 的最大值减去 \(X\) 的最小值的值。
给定两个长度为 \(N\) 序列 \(A=(A_1,\dots,A_N)\) 和 \(B=(B_1,\dots,B_N)\)。对于每一个 \(k=1,2,\dots,N\),解决以下问题:
- 求出序列 \(C=(C_1,\dots,C_k)\) 的最小价值且序列 \(C\) 满足 \(C_i\) 为 \(A_i\) 或 \(B_i\)。
\(1\le N\le 5\times 10^5,1\le A_i,B_i\le 10^9\)。
题解
最大/小化极差的套路是枚举其中一个并最大/小另一个。
设 \(f_i\) 表示最小值为 \(i\) 时的最小最大值,显然 \(f\) 是单调不降的,且答案是 \(\min(f_i - i)\)。
注意如果 \(i\) 并不存在于序列中也没关系,因为调大 \(i\) 一定不劣。
考虑加入一个数对 \((a, b)\),令 \(a \le b\)。那么应该有下面的变化:
因为 \(f\) 是单调的,区间取 \(\max\) 可以变为区间推平。直接上 odt 就结束了,复杂度 \(\mathcal{O}(n \log n)\)。
E (Replace Triplets)
题意
给定序列 \(A=(A_1,A_2,\cdots,A_N)\),其中 \(N\ge 3\)。
你可以进行以下操作若干次:
- 选择整数 \(i\) 满足 \(1\le i\le N\) 且 \(A_i=A_{i+1}=A_{i+2}\),将 \(A_{i},A_{i+1},A_{i+2}\) 三个数中的两个替换成 \(1\sim N\) 的整数。规定 \(A_{N+1}=A_1\),\(A_{N+2}=A_2\)。
求有多少种可能到达的状态,使得恰好是 \(1\sim N\) 的排列,答案 \(\bmod\ 998244353\)。
\(3\le N\le 5\times 10^5,1\le A_i\le N\)
题解
神秘题啊,会不了一点,Coner Case 满天飞,思维链长如小肠,快做崩溃了。
数列表上的数字替换有两个经典套路:
- 时光倒流。例如 ARC183B 中,将「把 \(a_i\) 变成 \(a_j\)」替换为「选择 \(a_i = a_j\) 并将 \(a_j\) 替换为任意数」。
- 连续同色压缩,如 \([1,1,1,2,2] \to [1,2]\)。ARC183B 中当 \(k=1\) 时就是用了这个东西判定的(\(A\) 能变成 \(B\) 当且仅当 \(B\) 压缩后是 \(A\) 的子序列)
时光倒流后,将题目转化化为:
给定序列 \(a\),有多少个排列 \(p\) 可以通过以下操作变成序列 \(a\)?
- 将 \(p\) 首尾相接形成一个环,在环上选择长度为 \(3\) 的子串将其所有数替换成原子串中的某个数。
注意本题操作是在环上的,接下来默认 \(a, p\) 首尾相接。
考虑合法 \(p\) 的充分必要条件,我们令 \(a'\) 是 \(a\) 压缩连续段后得到的序列,同样定义 \(p'\)。
先把平凡情况判了:
- \(a\) 是一个排列时,答案为 \(1\)。
- \(a\) 的所有元素相同的时候,答案为 \(n!\)。
- \(a\) 无法执行操作的时候,答案为 \(0\)。
判完 Corners,算出来 \(a'\) 的长度 \(s\) 之后 \(a'\) 和 \(a\) 就没用了,我们只关心 \(a'\) 里有几种数。
由于判完后 \(a\) 必有两数不等,于是可以循环位移使得 \(\color{red}{a_1\neq a_n}\),此时每个连续同色都没有跨过 \(1\sim n\)。
因为是环上,所以压缩的序列一样也可能有原序列会循环移位,那么我们先考虑什么样的 \(p\) 上的循环移位是可行的。
接下来我们考虑 \(A\) 中的不同数有 \(n - 2\) 个的情况,即恰好一个数可以操作,类似于 \(1, 1, 1, 2, 3, 4\),这样的序列能够生成多少种不同的排列呢?
如果只执行一次操作,我们可以获得 \(1, 5, 6, 2, 3, 4\),或者 \(1, 6, 5, 2, 3, 4\) 等等,即没有出现过的数字都围绕着 \(1\) 产生;如果执行两次,我们可以先让序列变为 \(1, 2, 2, 2, 3, 4\),然后就变成了第一次的情况。
以此类推,我们发现,在经过若干次之后,序列会变成 \(1, 2, 3, 4, 1, 1\),即所有字符向左移动了两位,因此我们可以证明,如果 \(n\) 为奇数或者 \(P\) 可被生成,那么 \(P\) 的任何环同构序列都可以被生成;\(n\) 为偶数的话就是 \(P\) 的任何右移 \(2\) 位产生的序列可以被生成;最后 \(n = 4\) 是特殊情况,因为我们可以令 \(1, 1, 1, 3\) 经过两步生成 \(3, 1, 1, 1\),其中 \(3\) 只移动了一位,但是 \(> 4\) 的偶数就不可以这么做。
再观察最开始没有在 \(A\) 中间的两个数字,这两个数字在 \(P\) 中距离(环上)一定小于等于于 \(2\),于是直接计数即可,具体过程就不细推了,大概就是考虑两个数字放在了哪个空位即可,答案为 \(4(n - 2)n\),当 \(n > 4\) 且 \(n \pmod 2 = 0\) 的时候要除以 \(2\)。\(n=4\) 所有排列均可生成。
最后的一种情况就是 \(A\) 中不同的数字小于等于 \(n - 3\),可以证明在保证 “\(A\) 中两个数的相对位置在 \(P\) 中得到保留” 这个条件的前提下,只要存在一对没在 \(A\) 出现但是但 \(P\) 中出现的数在 \(P\) 中的距离(环上)小于等于 \(2\) 的 \(P\) 都可以生成,具体的证明方法就是考虑最后一步生成的两个数的距离一定小于等于 \(2\),其余步可以随便移动并且生成即可。
我们通过容斥,转化为对 “\(A\) 中两个数的相对位置在 \(P\) 中得到保留” 并且任意两个没在 \(A\) 出现的数但是在 \(P\) 中出现的数在 \(P\) 中的距离(环上)大于等于 \(3\) 的 \(P\) 计数。
使用隔板法即可,你需要实现 \(f(n, m)\) 表示将 \(n\) 个球放到 \(m\) 个盒子中,并且每个盒子球数大于等于 \(2\) 的方案数,即 \(f(n, m) = \dbinom{n-m-1}{m-1}\)。
最后枚举第一个没在 \(A\) 中出现的数的放的位置,对于剩下的数使用 \(f\) 函数和阶乘处理答案即可,这一部分详见代码。
综上,时空复杂度均为 \(\mathcal{O}(n)\)。

浙公网安备 33010602011771号