ABC267题解

\(E\)

\(Problem\)

给定一张 \(n\) 个点 \(m\) 条边的无向图,点 \(i\) 有一个点权 \(A_i\)

接下来你要在这张图上进行 \(n\) 次操作,每次操作选择一个没有被选择过的点,删除该点以及所有和该点相连的边,定义删除该点的代价为所有与它直接相连的点的权值和。

接下来,你需要求出一个最小的阈值,使得每次操作的花费不得超过该阈值。

\(Scope\ Limitation\)

\(1\leq n\leq 2\times 10 ^ 5, 0\leq m \leq 2\times 10 ^ 5\)

\(Solution\)

很容易想到二分答案。

每次判断的方式也相当简单,设二分出的阈值为 \(x\),由于每个点的花费只会随着操作的进行而减小,所以只要一个点的花费小于阈值,就将其丢进队列,如果凭借这种方式能够遍历全图,则证明该阈值下,能够完成操作。

\(F\)

\(Problem\)

给定一个 \(n\) 个点的树,定义两点间的距离为两点最短路径经过边的数量。

给定 \(Q\) 个询问,每个询问给定两个值 \(U\)\(K\),询问树上是否存在与点 \(U\) 距离为 \(K\) 的点,若存在,输出任意一个,否则输出 \(-1\)

\(Scope\ Limitation\)

\(1\leq n\leq 2\times 10 ^ 5, 1\leq Q \leq 2\times 10 ^ 5\)

\(Solution\)

显然,对于每一个询问,我们需要找到距离 \(U\) 最远的点,则所有不为 \(-1\) 的答案都可以在其上找到。

不难想到处理出这棵树的直径,找到直径之后,以直径上的所有点为根,处理出不在直径上的点的倍增函数以及深度,则容易进行如下判断:

  • 若询问点深度大于等于 \(K\),则直接倍增向上跳。

  • 若询问点深度小于 \(K\),则直接跳到这棵子树在直径上对应的根,向更远的一段走即可。

\(G\)

\(Problem\)

给定一个长度为 \(n\) 的序列 \(A\)

求符合如下要求的长度为 \(n\) 的排列 \(P\)的数量:

  • 恰好存在 \(K\) 个不同的 \(i(i < n)\) 满足 \(A_{P_i} < A_{P_{i + 1}}\)

\(998244353\) 取模。

\(Scope\ Limitation\)

\(1\leq n\leq 5000,1\leq A_i\leq n\)

\(Solution\)

不难发现,题意等价于重新排列 \(A\)

考虑一种确定新的排列 \(A'\) 的方式,我们将 \(A\) 中的元素从小到大放入 \(A'\)

初始时,令 \(A' = \{0,0 \}\),如果最后的序列形如 \(\{2,1,3\}\),那么,\(A'\) 变化的过程依次为:\(\{0,1,0 \},\{0,2,1,0 \},\{0,2,1,3,0 \}\)

由于 \(A_i\) 不小于 \(1\),我们插入的元素必须在两个 \(0\) 之间,所以有一个多余的贡献,则我们最后需要 \(K + 1\)\(A_i < A_{i + 1}\)

由于我们规定的顺序,思考插入一个数之后 \(A_i < A_{i + 1}\) 数量的变化:

  • 首先,插入一个 \(x\)\(A_i < A_{i + 1}\) 之间,此时其数量必然不会发生变化,因为 \(x\geq A_{i + 1} > A_i\)
  • 若插入一个 \(x\)\(A_i >= A_{i + 1}\) 之间,此时数量可能会增加 \(1\),但是需要注意相同的数的数量,所以我们需要维护一个变量,记录已经插入到 \(A'\) 中和 \(x\) 相同的数的数量。

于是我们维护 \(dp_{i,j}\) 表示插入了 \(i\) 个数,有 \(j\) 个位置满足 \(A_i< A_{i + 1}\),则可以在 \(O(nK)\) 的时间复杂度内解决该为题。

\(Ex\)

\(Problem\)

给定一个长为 \(n\) 的序列 \(A\),求该序列有多少个包含元素个数为奇数个的子序列,满足其和恰好为 \(M\),答案对 \(998244353\) 取模。

\(Scope\ Limitation\)

\(1\leq n \leq 2\times 10 ^5,1\leq M\leq 10 ^6,1\leq A_i\leq 10\)

\(Solution\)

定义一个 \(dp_{i,j}\) 为当前选择的元素的和为 \(i\),元素个数模 \(2\)\(j\) 的方案数。

直接转移复杂度达到了 \(O(nM)\),显然不可取。

\(dpx'_i = \sum_{j = 0}^∞ dp_{j,i}x^j\),即 \(dpx'_i\) 为一个多项式,元素的和 \(j\)\(x\) 的质数,设已知两个多项式 \(dpx'\)\(dpy'\),考虑如何将其转移为 \(dpz'\)

  • \(dpz'_0 = dpx'_0\times dpy'_0 + dpx'_1\times dpy'_1\)
  • \(dpz'_1 = dpx'_0\times dpy'_1 + dpx'_1\times dpy'_0\)

即为一个卷积运算。

那么,我们将初始的若干个元素,每个元素单独成立一个多项式,并将其加入一个多项式的集合 \(f\),每次,我们取出 \(f\) 中的前两个元素,将他们卷积,再放入末尾。

虽然多项式的长度质数级增长,但 \(f\) 中的元素个数同样质数级减小,故而我们可以在 \(\mathcal O(nlognlogM)\) 的时间复杂度内解决这个问题。

更具体的,对于元素 \(A_i\),我们令其对应的多项式,零次项和 \(A_i\) 次项系数设为 \(1\),分别代表空集和单独选择元素 \(A_i\),这样我们做出来没有考虑奇偶性,最后多项式的 \(M\) 次项对应的答案为奇数加偶数。

我们再做一遍同样的过程,这次将零次项系数设为 \(1\)\(A_i\) 次项系数设为 \(-1\),这样卷积过后,最后多项式 \(M\) 次项对应的答案为偶数减奇数。

将两次答案相减,可得两倍奇数,除二即为正确答案。

posted @ 2022-09-04 20:10  ╰⋛⋋⊱๑落叶๑⊰⋌⋚╯  阅读(112)  评论(1编辑  收藏  举报