ARC180 做题记
A (ABA and BAB)
题意
给定一个由 A 和 B 组成、长度为 \(N\) 的字符串 \(S\)。
你可以以任意顺序重复进行以下两种操作 \(0\) 次或多次:
- 在 \(S\) 中选择一个连续的子串
ABA,并将其替换为A。 - 在 \(S\) 中选择一个连续的子串
BAB,并将其替换为B。
请你求出经过若干次操作后,可能得到的不同字符串的数量,并对 \(10^9+7\) 取模。
\(1 \leq N \leq 250000\)
题解
对于每个极长的 \(AB\) 交替段单独考虑,每个是独立的。
长度为 \(l\) 的段贡献是 \(\times \lfloor\frac{l+1}{2}\rfloor\),直接计算即可。
B (Improve Inversions)
题意
给定一个 $ (1,2,\cdots,N) $ 的排列 $ P=(P_1,P_2,\cdots,P_N) $,以及一个整数 $ K $。
你可以进行如下操作 $ 0 $ 次或多次:
-
选择整数 $ 1\le l\lt r \le n$,但需满足以下所有条件:
-
$ K\leq r-l $。
-
当前 $ P_l>P_r $。
-
之前从未选择过同一组 $ (l,r) $。
-
-
然后交换 $ P_l $ 和 $ P_r $ 的值。
你希望最大化操作次数。请给出一种实现方法。
$ 2\leq N\leq 500 ,1\le K<N$
题解
逆天贪心题。
贪心策略: 枚举 \(1 \cdots n\) 的每个数 \(i\),每次找出所有比它小的能和它交换的数,从大到小依次交换。称其为第 \(i\) 轮交换。
现在证明正确性。
首先证明交换次数为 \(\sum\limits_{i=1}^n \sum\limits_{j=i+k}^n [a_i \ge a_j]\)。
注意到,考虑每个数 \(i\) 的时候所有数只有大于 \(i\) 和等于 \(i\) 的区别,而枚举 \(1 \cdots i-1\) 的时候交换数都小于 \(i\),不会对此产生影响。
再证明答案最大值为 \(\sum\limits_{i=1}^n \sum\limits_{j=i+k}^n [a_i \ge a_j]\)。
注意到它等价于把每组合法的交换方案拉出来同时执行。
如果进行了交换 \(i,j\) (\(i<j\)),那么 \(a_i\) 肯定变小,\(a_j\) 肯定变大。
所以,对于 \(u \le i-k\) 或 \(u > j-k\),显然以它为左端点的合法交换方案数不变;对于 \(i-k < u \le j-k \wedge u \ne i\),以它为左端点的合法交换方案数最多减一;如果 \(u=i\) 则至少减少一。
因此答案最大值就是初始的合法方案数,所以贪心策略是正确的。
C (Subsequence and Prefix Sum)
题意
给定一个长度为 \(N\) 的整数序列 \(A=(A_1,A_2,\cdots,A_N)\)。
你需要恰好进行 \(1\) 次如下操作:
- 选择 \(A\) 的一个 非空子序列,并将其替换为其前缀和序列 。
请你求出,操作后可能得到的不同 \(A\) 序列的个数,结果对 \(10^9+7\) 取模。
\(1 \leq N \leq 100,\vert A_i \vert \leq 10\)
题解
一个很显然的想法是 dp,设 \(f_{i,j}\) 代表前 \(i\) 个数,目前选的东西总和为 \(j\) 的方案数。
转移也显得很对,但是在 \(j=0\) 时会出问题。
原因是 \(j=0\) 代表下一次选择数的时候不会对它造成影响。同时,考虑如下输入:
4
0 1 1 2
如果选择了 \(0,1,2\) 的话,这个 dp 会把两种选择方案全部算进去,但你无法分辨具体选的是哪一种。
所以开一个 \(g\) 数组记录目前总和为 \(j\) 且上一次总和为 \(0\) 的方案数。
考虑到一个总和为 \(0\) 的方案下一次选的数只要值相同那么选哪一个没有区别,所以每次给 \(g_{a_i}\) 赋值 \(g_0\),再给 \(g_0\) 赋值 \(f_{i,0}\) 就行了(其他的 \(g\) 值直接转移到 \(f\) 上面去)
D (Division into 3)
题意
给定一个长度为 \(N\) 的整数序列 \(A=(A_1,A_2,\cdots,A_N)\)。请回答以下 \(Q\) 个查询。
-
第 \(i\) 个查询:给定整数 \(L_i,R_i\)。对于 \(B=(A_{L_i},A_{L_i+1},\cdots,A_{R_i})\),解决如下问题:
- 将 \(B\) 分割为 \(3\) 个非空的连续段。对于每个连续段,求出其元素的最大值。求这些最大值之和可能取得的最小值。保证存在至少一种分割方法。
\(3\leq N,Q\leq 250000,1\leq A_i\leq 10^8,R_i-L_i\geq 2\)
题解
分类讨论原来最大值在第几个连续段。
若在中间的段,则左右两个段长度为 \(1\) 一定是最优。
否则在第一个和第三个本质相同,不妨假设在第一个。剩下的 reverse 序列再做一遍。
不妨假设 \(B\) 到 \(C\) 的分界点被固定,因为 \(A\) 的代价已经确定,那么 \(B\) 长度越小,\(B\) 的代价就越小,总代价就越小。
因此 \(B\) 的长度恰好为 \(1\)。记 \(x\) 表示 \(\min\limits_{i=l}^{r} i [a_i = mx]\),那么总代价即为:
记 \(f_i = a_i + \max\limits_{j=i+1}^{r} a_j\),使用扫描线维护固定 \(r\) 时,所有的 \(f_i,i\le r\)。
用单调栈+线段树是容易维护的。复杂度 \(\mathcal{O}((N+Q)\log N)\)。
E (LIS and Inversion)
题意
给定一个长度为 \(N\) 的整数序列 \(A=(A_1,A_2,\cdots,A_N)\)。这里,保证对于每个 \(i\),有 \(0\leq A_i < i\)。
对于 \((1,2,\cdots,N)\) 的一个排列 \(P=(P_1,P_2,\cdots,P_N)\),定义其 分数 和 代价 如下:
- \(P\) 的分数为 \(P\) 的最长递增子序列的长度。
- \(P\) 的代价为满足以下条件的整数 \(i\) 的个数:
- 满足 \(j<i\) 且 \(P_j>P_i\) 的整数 \(j\) 的个数小于 \(A_i\)。
对于每个 \(k=1,2,\cdots,N\),请解决下列问题:
- 求分数至少为 \(k\) 的排列 \(P\) 的最小代价。
\(1\leq N\leq 250000,0\leq A_i < i\)
题解
很牛的题!
注意到逆序对和 LIS 都只是用只关注相对大小的,所以设计状态的时候大抵是要跟相对大小的排名有关的。
LIS 并不好放入状态,考虑将其设为 dp 数组的答案。
定义成本为 \(n-\) 代价,即 \(\ge a_i\) 的对成本贡献 \(1\)。
那么考虑将成本为 \(0\) 的时候最大得分是多少。
设 \(f_{i,j}\) 表示考虑了前 \(i\) 个位置,LIS 以第 \(j\) 大数为结尾的最长长度是多少。
\(f_{i,j} = \max \begin{cases} f_{i-1,j} \\ f_{i-1,j-1} & j > a_i + 1 \\ f_{i-1,k} + 1 & k \ge j > a_i \end{cases}\)
最后 \(\max f_{n,j}\) 即为最长 LIS。
根据定义我们可以推出 \(f_{i,j-1}-1 \le f_{i,j}\),因为交换第 \(j\) 大和第 \(j+1\) 大答案之多变化 \(1\)。
- 于是能推出第二种转移是无用的!
然后你注意看 \(k > j\) 的转移也是无用的!
因为你每次更新都是 \(j\) 越大,答案才越有可能变大。
那对于 \(k\),转移到 \(k > j\) 肯定是不优没有转移到 \(k = j\) 优的。
那么现在的转移变为:\(f_{i,j} = f_{i-1,j} + [j > a_i]\)。
那么对于每一列分别考虑,最终答案即为:
现在再考虑成本不为 \(0\),成本加 \(1\) 等价于将一个 \(a_j\) 变成 \(0\),设成本为 \(x\),那么答案即为:
\(g_i\) 差分即可求得,然后求个前缀最大值就好了。
F (Yet Another Expected Value)
题意
给定整数 \(N, A\)。
你将进行如下操作:
- 随机生成 \(N\) 个 \(0\) 到 \(1\) 之间的实数。所有生成都是独立且服从均匀分布的。
- 将生成的 \(N\) 个实数按从小到大排序,记为 \(x_1, x_2, \cdots, x_N\)。即 \(0 \leq x_1 \leq x_2 \leq \cdots \leq x_N \leq 1\)。
- 你的得分为下式的值:
请计算得分的期望值,并对 \(10^9+7\) 取模。
\(1 \leq N \leq 10^4,1 \leq A \leq 5 \times 10^4\)
题解
本文完善(瞎解释)了一些推导过程,稍微写详细一些,就是硬算算算。
记 \(a_n(y)\) 表示以下问题的答案期望:
在 \([0,y]\) 上均匀随机 \(n\) 个实数 \(x_1, \dots, x_n\),若满足 \(x_1 < x_2 < \dots < x_n\),则答案为 \(\prod\limits_{i=1}^n \left(y^A + \sum\limits_{j>i} x_j^A\right)\),否则为 \(0\)。
原命题答案明显是 \(n! \times a_n(1)\)。写出 \(a_n(y)\) 的生成函数 \(f(y, x) = \sum\limits_{i \ge 0}a_i(y)x^i\)。
- 不妨有 \(a_0(y)=1\)。
考虑 \(a_n(y)\) 的组合意义是什么。考虑乘法分配律拆连乘,相当于对于每一个 \(i\) 选出一个 \(j > i\) 的 \(x_j^A\) 或者 \(y^A\)。
考虑抽象成一棵树,令 \(i\) 号点的权值为 \(w_i=x_i^A\),\(0\) 号为 \(w_0=y^A\)。
若 \(i\) 选择了 \(j>i\),连边 \((i\to j,w_j)\),否则连边 \((i\to 0,w_0)\)。
对于每种树,贡献是所有边权的乘积。
考虑剥根,枚举 \(0\) 号点连了 \(k\) 棵子树,每颗子树的贡献递归用 \(f\) 表示。
然后由于子树间无序,发现要 \(\times \frac{1}{k!}\),即是一个 \(\exp\) 形式。
(用积分)枚举 \(0\) 号点的权值为 \(0\le t\le y\),写出这个 \(\exp\):
- 注意把每颗子树的根现在被看成了虚拟的 \(0\) 号点,于是要枚举它的信息和计算贡献。
- \(x^k\) 是因为贡献了 \(k\) 个点作为子树的根。\(y^{Ak}\) 是 \(w_0\) 的贡献,\(t\) 是枚举每颗子树根的权值。
如何解这个方程呢?
由于 \(f(y,x)\) 是关于 \(x\) 的多项式,有多项式形式不用白不用,左右取 \([x^n]\):
考虑写几项看看,\(\exp\) 用泰勒展开:
-
当 \(n=1\) 时,\(a_1(y)=y^A{\displaystyle \int_0}^y 1 dt=y^{A+1}\)。
-
当 \(n=2\) 时,\(a_2(y)=[x^2]\left(\frac{1}{2}(xy^{A+1})^2+x^2y^A{\displaystyle \int_0}^y a_1(y) dt\right)=(\frac{1}{2}+\frac{1}{A+2})y^{2(A+1)}\)。
发现 \(a_n(y)\) 应该只有 \(y^{n(A+1)}\) 这一项。
我们容易归纳证明 \(a_n(y)=g_ny^{n(A+1)}\),特别的 \(g_0=1\)。
有了这个结论,我们发现 \(y\) 这个变量我们 已经不关心了,把里面积分算一下。
然后带入原来恒等式,丢掉所有 \(y\):
记里面的东西为 \(h\),就有 \(g,h\) 的互相递推:
- \(g_n=[x^n]\exp h=\frac{1}{n}\sum\limits_{k=1}^n kh_kg_{n-k}\)
- \(h_n=[x^n]\sum\limits_{k\ge 0} \frac{g_k}{1+n(A+1)}x^{k+1}=\frac{g_{n-1}}{1+(n-1)(A+1)}\)
第一行第二个等号是用了 n^2 多项式全家桶 里面的方法算 \(\exp\)。
于是容易 \(\mathcal{O}(n^2)\) 递推出 \(g,h\)。足以通过此题。
- 注意答案是 \(n!g_n\) 而不是 \(g_n\)。
如果是一个 NTT 模数,比如 \(998244353\),那如何做到更优复杂度呢?
考虑类似 cdq 分治那样做分治 NTT,能做到 \(\mathcal{O}(n\log ^2n)\),比如 这份代码。

浙公网安备 33010602011771号