Solution Set #4

Construction

[UOI 2023] An Array and Addition Again

简单题。先倒着操作把 \(a_i\) 全改成 \(1\),然后考虑问题:如何把 \(a_x\) 改成 \(y\)。

若 \(y\) 是奇数,则只需把 \(a_{x+1}\) 变成 \(\dfrac{y-1}{2}\),然后操作两次 \(x\);否则,先操作 \(x\) 把 \(a_x\) 变成 \(2\),然后把 \(a_{x+1}\) 变成 \(\dfrac{y}{2}-1\),然后操作两次 \(x\)。\(y=2\) 特判一下。

操作次数是 \(k+3\log_2 n\),可以通过。

[POI 2017] Turysta

考虑答案的上界是 \(u\) 可达点的数量,可以证明这个上界能取到。证明就是,强连通竞赛图一定存在哈密顿路,只需要让 \(u\) 走完所在 scc,然后去走下一个 scc,以次类推。

\(O(n^2)\) 做法:对每个 scc 求一个哈密顿回路,然后对于每个点就可以直接 \(O(n)\) 回答构造。求哈密顿路径考虑增量加入即可,求回路同样增量,先基于回路,令初始环为路径的起点,每次找一个能连到环上的点,把环变大,这样总是可以在 \(O(n^2)\) 的时间内求出哈密顿回路,就做完了。

\(O(n^3/\omega)\) 做法:是来自 @Makab 的。下面证,“以 \(u\) 为根的 dfs 树的后序遍历的 reverse” 是合法构造:

先证明一个引理:对于 dfs 树上任意一对无祖先关系的点,在原图上边的方向为从 dfn 大的点向 dfn 小的点。考虑反证:不妨设这两点为 \(u\),\(v\) 且 \(dfn_u < dfn_v\)。若此边的方向为 \(u\to v\) ,则在访问 \(u\) 后,\(v\) 会被 \(u\) 子树中某点访问(注意 \(v\) 不会早于 \(u\) 被访问,因为钦定了 \(dfn_u < dfn_v\))。

即这两点在 dfs 树上有祖先关系,矛盾。再考察 dfs 树的后续遍历 \(\{a\}\),对于任意 \((a_i, a_{i + 1})\),必然存在边 \(a_i \leftarrow a_{i + 1}\)。

证明:考虑 \(a_i\) 要么是 \(a_{i + 1}\) 的儿子;要么 \(a_i\) 与 \(a_{i + 1}\) 无祖先关系,且 \(dfn_{a_i} < dfn_{a_{i + 1}}\),有引理得存在边 \(a_i \leftarrow a_{i + 1}\)。所以倒着输出即可。

构造方案使用 bitset 优化 dfs 即可。

Bring Balance

考虑限制答案的上界。

不难发现答案不超过 \(2\):记 \(mx\) 为前缀和最大值位置,操作 \([1,mx]\) 和 \([mx+1,n]\) 即可。

答案是否为 \(0\) 容易判定,只需判定答案是否为 \(1\)。可以做 \(l\) 和做 \(r\) 是一段前缀 \([1,L]\) 和后缀,因为要求 \(\min_{i\le l}s_i\ge 0\) 和 \(\min_{i\ge r}s_i\ge 0\)。\(l,r\) 之间的限制为 \(p\in [l,r],s_{l-1}+s_r-s_p\ge 0\),不难发现 \(l\) 直接取 \(s\) 最大的即可,这样可以保证 \(p\in [l,L]\) 都满足,因此我们可以线性判定。时间复杂度 \(O(n)\)。

graph & tree

Twin Binary Trees

答案显然是枚举叶子 \(x,y\),计算 \(f(x,y)f(p_x,p_y)\) 之和,其中 \(f\) 表示树上 \(x-y\) 路径的点权积。

枚举在 \(T_1\) 上的 lca \(u\),再枚举 \(T_2\) 上的 lca \(v\)。显然 \(u\) 子树内叶子的所有祖先才可能成为 \(v\),故 \(v\) 只有 \(O(siz_u\log n)\) 种。直接在 \(T_2\) 中的这些点上 DP 即可。

时间复杂度 \(O(n\log^2 n)\)。

Two Trees

图论建模。

考虑直接刻画 \(x\) 较为复杂,考虑令 \(s1_u,s2_u\) 表示在 \(T_1\) 和 \(T_2\) 上的子树和。

一个显然的必要条件是子节点个数奇偶性相同,我们将证明这是充要的。

显然满足:\(s1_u-\sum_{x\in son_1(u)}s1_x=s2_u-\sum_{x\in son_2(u)}s2_x\)。

发现这个东西很像入度与出度的差,这很欧拉回路。你发现 \(s1_i=1\) 就定向 \(i\to fa_i\),反之定向 \(fa_i\to i\);\(s2\) 的定向与前面相反。因此对于一组欧拉回路就总能给出一组解,只需要把这个环的定向结果倒推出 \(s1,s2\) 即可。

此时,左式减去右式相当于限制 \(in_u=out_u\),因此只需要把两棵树叠在一起跑欧拉回路即可。其中建超级源点 \(0\) 并连接两颗树的根。

时间复杂度 \(O(n)\)。

ee

先考虑如何判定 \(G\) 包含四元环,相当于判定是否存在 \(x,y\) 满足连边的交 \(\ge 2\),先钦定其中交的一个点 \(u\),则相当于判定 \(u\) 的邻居的非 \(u\) 邻居是否有交,显然找到一个交就退出复杂度是 \(O(n)\) 的,这样枚举所有 \(u\) 就可以 \(O(n^2)\) 判定。

考虑如何推广到 \(q\) 更大的情况。神秘均摊一下。发现可以维护集合 \(S\) 表示待判定集合,每次取出一个点若判定不合法就删除,否则返回可行。

对于每次加边 \(x-y\),只需加入点 \(x,y\) 即可,因为上面的判定对于四元环上任意一个点都会生效。

\(S\) 最多加入 \(n+2q\) 个元素,一个点的判定是 \(O(n)\) 的,时间复杂度 \(O(n(n+q))\)。

Advanced Evolution Studies

限制 lca,一个简单的想法是自下而上合并连通块,但怎么合并比较复杂,因为能合并就合并是有后效性的。

考虑反过来变成分裂,我们希望尽可能分成更多的连通块。考虑当前的限制为:

  • \(a,b\) 属于相同连通块;
  • 若 \(c,d\) 属于相同连通块,则 \(a,b,c,d\) 属于相同连通块。

因此,考虑每次合并连通块时,我们找到所有需要继续合并的连通块,直到无法合并为止,然后递归子问题。若合并出来一个连通块就是无解。

视 \(n,m\) 同阶。朴素实现是 \(O(n^3)\) 的,因为这个子问题最坏递归 \(n\) 次,合并 \(n\) 次,每次有 \(n\) 个限制。

考虑优化,把限制挂在 \(c\) 和 \(d\) 上,类似启发式合并,每次扫描较小连通块对应的限制,复杂度就是 \(O(n^2\log n)\) 的,足以通过。

Judge Error

手玩一下发现边双应该是无解的,证明。

考虑每次把割边找出来,如果分裂的连通块大小是奇数,则选择这组匹配,将这条割边和这两个点删去;否则不选择并删去割边。然后递归子问题即可。

朴素使用 tarjan 判定是 \(O(nm)\) 的,无法通过。

找割边的步骤是容易使用 bitset 加速的。先找一颗 dfs 树,这容易用 bitset 优化。然后,我们维护每个子树的出边并,也可以 bitset,然后如果一个子树出边并没有外面的子树的点,则它的父边就是割边。

这样就做到了 \(O(n^3/\omega)\)。

Black Radius

先讨论 \(s_i=1\)。下面约定 \(u\) 的 \(d\) 级邻域是所有距离 \(u\le d\) 的点。

\(u\) 的 \(d\) 级邻域的直径中点为 \(r\),则一定存在 \(d'\) 满足 \(r\) 的 \(d'\) 级邻域是 \(u\) 的 \(d\) 级邻域。(这里认为边到两侧的点距离都是 \(0.5\))

因此,对于邻域的直径中点在点上的情况,考虑 \(d\) 的取值范围,显然下界是 \(0\)。发现上界是次深的子树深度(若大于 \(d\),则新扩出去的点只属于最深子树深度或者不再扩展,会算重或者不是中点)。

对于直径中心在边上的情况,显然会填满一侧的子树,而且是恰好填满后把另一侧填的一样满,否则直径中点就偏移了。因此贡献是 \(1\)。

考虑 \(s_i\) 不为 \(1\) 怎么办。

对于在点上的情况,下界 \(0\) 不再能取到。发现一定是找一个最浅有 \(1\) 的子树把它填满,因此下界是最浅有 \(1\) 的子树深度。

对于在边上的情况,显然是把最小的填满,则只需要判定最小的那侧是否有 \(1\) 即可。

时间复杂度 \(O(n)\)。

[JOISC 2020] カメレオンの恋

先考虑 \(O(n^2)\) 怎么做。

发现询问 \(\{u,v\}\) 结果为 \(1\),则说明 \(u,v\) 性别不同,分析条件可能是:

  • 颜色相同
  • \(u\) 喜欢 \(v\) 且 \(v\) 不喜欢 \(u\)
  • \(v\) 喜欢 \(u\) 且 \(u\) 不喜欢 \(v\)

因此对于度数为 \(1\) 的点可以直接确定与它配对的颜色。对于度数为 \(3\) 的点,分别称这三个点为 \(x,y,z\),则发现查询 \(\{u,x,z\}\) 时结果为 \(1\),否则结果为 \(2\)。标记这条边 \(u,y\),最后对于所有点找到未被标记的边即可。

这样就有一个 \(O(n^2)\) 做法,瓶颈在于找出图中所有的边。

若性别已知,可以直接用二分做到 \(O(n\log n)\)。

考虑原问题直接二分有什么困难,在于有同性会干扰判定。更进一步的,我们可以发现 \(S\) 内出现干扰当且仅当 \(S\) 不是独立集。

因此考虑增量加入 \(1\sim 2n\) 的所有点,增量求出所有边 \(i,j(j<i)\)。每次对新图黑白染色,然后对所有独立集二分即可。

操作次数是 \(O(n\log n)\) 的,可以通过。

【MX-X8-T5】「TAOI-3」蓝宝石的存在证明

约定 \(n\ge 4\),定义叶子是一度点。

手玩一下树,发现叶子和它所连的点一定被分在一组,然后发现如果有点不与叶子相连就一定无解,证明考虑删去这个点后随便选一个连通块并上自己,就对应了 \(\ge 2\) 组解。反之,每个叶子必须和它指向的连在一块,解显然唯一。

事实上图也是类似的。考虑若删去 \(u\) 图不连通,则证明与树类似。否则,考虑找到 \(u\) 的两个邻居 \(x,y\) 在新图上的路径 \(x-p_1-p_2-\cdots-p_k-y\),每个点往外会挂若干个连通块。

若有点往外挂的连通块大小 \(\ge 2\),则把它归入它挂的连通块或者归入环就对应了两组解;否则每个点都连了叶子或者没连,由于 \(u\) 没有连,则考虑跟它的两个邻居哪个合并在一起也对应两组方案(特殊的,这个证明在只有一个三元环时失效)。

综上,\(G\) 满足条件当且仅当 \(G\) 中的非叶子节点都与叶子直接相连。

计数是简单的,维护 \(f_i\) 表示 \(i\) 个点的树/连通图个数,然后枚举叶子个数即可。答案为 \(\sum_{1\le i\le n}f_iS_{n-i,i}\binom{n}{i}i!\),容易在 \(O(n^2)\) 时间内预处理需要的信息。

0602

A / Snake Instructions

B / Elevator Against Humanity

tag:贪心,分类讨论

不考虑先后顺序,则相当于最大化 \(\sum_{i=1}^{2n}|p_i-p_{i-1}|\),约定 \(p_0=1\)。

走路肯定是 \(>n\) 的下标和 \(\le n\) 的下标隔着取。

发现基于这个不用调整很多。先让初始答案表示钦定 \(\le n\) 的下标都选择贡献 \(-2\),其它选择贡献 \(+2\),最后退掉最后一步的贡献。

若有 \(>n\) 的起点,我们钦定它是 \(p_1\)

C / Cycle Closing

tag:构造,树的直径

考虑只有两步操作,连 \(k=2\) 之后考虑能干什么。

走哈密顿路是不可行的,参考 Travelling Trader,需要到 \(k=3\) 才可以。

考虑 \(dis\) 的上界是树的直径除以 \(2\),令 \(d\) 为这个值。

那我们只需要,对于 \(u,v\) 构造这个路径 \(p\),满足相邻两个距离为 \(1\) 或 \(2\)。

先特判 \(dis\ge d\) 的情况,两步两步跳一部分,一步一步跳一部分就可以。

对于 \(dis<d\),先两步两步跳到直径上,然后选多的那边跳,走法形如 \(x\to x+2\to \cdots\to x+2m\to x+2m\pm 1\to \cdots \to x+1\) 就能走一个环回来,因此能浪费的步数的上界至少可以达到直径长度的一半,因此我们得到了一个合法的构造。

D / Clacking Balls

tag:停时定理

对球之间的距离设计势能函数,认为 \(f(0)=0\)。

\[E(\sum_{i=0}^{n-1} f(a'_i))=\sum_{i=0}^{n-1}f(a_i)+1 \\ \dfrac{1}{n}(\sum_{i=0}^{n-1} f(a_i-1)-f(a_i)+f(a_{(i+1)\bmod n}+1)-f(a_{(i+1)\bmod n}))=1 \\ d(i)=f(i)-f(i-1) \\ \sum_{i=0}^{n-1}d(a_i)-d(a_i-1)=n \]

不难发现,若设 \(d(x)-d(x-1)=\dfrac{xn}{m}\),因为 \(\sum x=m\)。

因此有 \(d(x)=\dfrac{n}{m}\binom{x+1}{2},f(x)=\dfrac{n}{m}\binom{x+1}{3}\)。

因此我们可以 \(O(1)\) 计算 \(f\),原问题得以解决。

思维题

总结 如果没有头绪,可以考虑分析:
  • 特殊情况:树是链的时候我们会不会,所有区间都是单点我们会不会,没有修改我们会不会,区间不扩张我们会不会......

  • 分析第一个操作/最后一个操作:什么情况下这个操作是有用的,有用时会造成什么影响,如果没用是不是可以直接将这个操作删掉。(考虑性质最好的元素是啥)

  • 递归考虑:考虑删除最小元素/最大元素/第一个元素/最后一个元素,新的序列有一个答案,我们再加入这个元素,考虑答案的变化量。(例:AGC014F Strange Sorting)

  • 从前到后贪心考虑/从小到大贪心/...:第一个/最小的...需要被覆盖,我们至少需要进行哪些操作。

  • 考虑是否有“两个元素是等效的”(比如第一个和最后一个),如果有,是否能直接把这两个元素合并起来,然后不断合并直到只剩一个元素。(例:AGC023D Go Home)

  • 多个操作的时候,分析一种操作是不是可以调整到某些位置操作不变劣。(或者分析最优情况操作的结构可以调整成什么样子)

  • 感觉正着操作时,限制在操作的过程中变得越来越紧,不好决策每个时刻干的事情:考虑时间反转。

  • 发现一些简炼的必要条件,堆砌起来,考虑是否有充分性:如果没有充分性,就能找到反例,继续堆砌必要条件。(例:AGC012F Prefix Median)

  • 发现一些充分条件,取并,看看是否还有不满足任意一条的情况,如果有,继续加入进去,取并。

  • 对于构造型题目,可以猜答案,之后考虑构造。(有的时候可以猜答案很小或者与理论最优解的差不大;例:AGC025E Walking on a Tree)

  • 强化已有性质,例如把 “正反都经过至少一次” 变成 “正反经过的次数差 \(\le1\)”。(例:AGC025E Walking on a Tree)

  • 弱化模型需要满足的条件。(例:AGC025E Walking on a Tree、AGC029F Construction of a tree)

  • 很多时候,如果不好找需要满足的条件的好的表达方式,可以考虑把需要满足的条件用公式的形式写出来,因为很多时候,有一些不变量被我们忽略了,可能移一下项就做完了,而我们不写公式可能就是想不到。(例:AGC028E High Elements)

Pushing Balls

考虑直接 DP 啥的很难做到 \(O(n)\)。考虑观察问题的结构,设 \(F(d_1,d_2,\cdots,d_{2n})\) 表示球洞距离依次是 \(d_1,d_2,\cdots,d_n\),则每次转移构成了一个子结构。

具体的,每删去一个球和一个洞,我们就把剩下的球和洞找出来,然后重新求出 \(d'\)。

注意到答案肯定是形如 \(\sum d_if_i\),换言之每个 \(d\) 的贡献系数与其它 \(d\) 是无关的,只和 \(n\) 有关系。由期望线性性,这启发我们直接递归子问题 \(F(E(d'_1),E(d'_2),\cdots,E(d'_{2n-2}))\),然后加上当前的期望贡献 \(\dfrac{\sum_{i=1}^{2n}d_i}{2n}\)。

考虑 \(E(d'_i)\),分析一下可以发现若 \(d\) 是等差数列,则 \(d'\) 也是。因此每个子问题都可以 \(O(1)\) 计算。

更进一步的,其实我们只关心 \(d\) 的平均值,因此按照段长考虑即可得到和式 \((\sum_{i=1}^{2n}d_i)(\sum_{i=2}^{n+1}\dfrac{1}{i})\),更简洁一点。

Go Home

正着考虑比较苦难,因此倒着考虑问题。

考虑最后送完的人一定是 \(1\) 号或者 \(n\) 号,而最后送的一定是人数少的那个。

证明考虑,记 \(rem\) 表示当前车上除了 \(1,n\) 以外的人数。则若 \(p_1\ge p_n+rem\),则车能开到 \(1\);若 \(p_n>p_1+rem\),则车能开到 \(n\)。因此若 \(p_1\ge p_n\) 一定先开到 \(1\),否则先开到 \(n\)。

不妨假设先开到 \(1\),则 \(n\) 希望 \(1\) 尽可能早送完,因为后面一定是从 \(1\) 去送他,因此只需把 \(p_1\gets p_1+p_n\) 处理子问题即可,直到 \(x_1>s\) 或 \(x_n<s\),此时一定是直接开过去。

Strange Sorting

考虑全局最小值并不是一个很关心的角色——它不会影响其它点是否是 high/low,把它删了对于其它点的序列是不变的。

因此,只需考虑 \([2,n]\) 排序后形成的序列,\(1\) 是否自动在最开头——若不是则答案加上 \(1\),直接模拟就可以做到 \(O(n^2)\)。

接下来是一个很神秘的观察。设前 \(t-1\) 次排序后序列最开头的数是 \(u\),则我们只需要判定,是否有 \(1\) 的位置在 \(u\) 和 \(2\) 之间。

性质:\((1,2,u)\) 的顺序关系始终循环同构。

引理:一个非首位 high 元素 \(x\) 一定无法移动到首位。证明考虑,它上一个 high 元素 \(y\),则下一次一定是 \(yx\) 连续出现。

考虑此时若 \(xy\) 都是 low 或都是 high,则 \(x\) 永远在 \(y\) 后面,不可能到开头。

若 \(y\) 是 low,\(x\) 是 high,则 \(x\) 仍然是非首位 high 元素,归纳即可。

因此 \(u\) 作为 high 时一定在首位。

考虑 \(u,1,2\) 的情况,\(u\) 是 high,\(1,2\) 是 low,变为 \(1,2,u\);

否则,\(u\) 一定是 low。\(1,2,u\) 的情况,一定变为 \(1,2,u/u,1,2\);\(2,u,1\) 一定变为 \(u,1,2\) 或 \(2,u,1\)。

综上:我们只需要判定初始顺序是否与 \((u,1,2)\) 循环同构即可,若同构则直接排好,否则需要多排一次。

\(O(n)\) 扫一遍,维护 \([i,n]\) 排序的情形,每次增量的加入全局最小值即可。

Walking on a Tree

很容易猜到记 \(d_i\) 为第 \(i\) 条边被覆盖的次数,则 \(ans=\sum_{i=1}^n\min(d_i,2)\)。

边正反走两次,考虑欧拉回路。但直接连边 \(x-y\) 得到的图不一定有欧拉回路。

考虑对于所有树边,若度数不对就在每个点和父亲连一条边,从叶子往上依次做,然后对新图跑无向图欧拉回路。

考虑正确性,对于覆盖一条的一定满足了,对于覆盖两条的一定至少有一条路径入子树,一条路径出子树,因此一定能满足条件。

时间复杂度可以做到 \(O(n\log n+m)\)。

【UR #31】决战中途岛

tag:反射容斥,二元 GF

将 \((x,y)\to (x+y,y-x)\),则相当于可以走 \((x,y\pm 2),(x\pm 2,y),(x+2,y-2),(x-2,y+2)\),贡献系数为 \(1\);或者走 \((x,y)\),贡献系数为 \(2\)。

方便期间把走的距离除以 \(2\)。

此时相当于要求不能走出第一象限,考虑做六边形反射容斥:

就是走出限制就对着线翻转一下就可以。

这样,我们只需要处理 \(6\) 个无限制的问题,问题形如,从 \((0,0)\) 按照上述方式走 \(k\) 步走到 \((x,y)\) 的方案数。

\[\begin{aligned} res &= [x^ny^m](x+\dfrac{1}{x}+y+\dfrac{1}{y}+\dfrac{x}{y}+\dfrac{y}{x}+2)^k \\ &= [x^ny^m](\dfrac{(x+y)xy+(x+1)x+(y+1)y+2xy}{xy})^k \\ &= [x^ny^m](\dfrac{(x+y)(x+1)(y+1)}{xy})^k \\ &= [x^{n+k}y^{m+k}](x+y)^k(x+1)^k(y+1)^k \end{aligned} \]

枚举第一个 \((x+y)^k\) 中选了几个 \(x\) 即可解决,时间复杂度 \(O(k)\)。

因此,原问题得以在 \(O(h)\) 的时间复杂度内解决。

0603

A

题意:

给定一颗 \(n\) 个点的树,每个点有颜色 \(col_i\)。

称点 \(u\) 拥有颜色 \(c\) 当且仅当存在一对点 \(p,q\) 满足 \(col_p=col_q\) 且 \(u\) 在 \(p\) 到 \(q\) 的简单路径上。

\(q\) 次操作,分为两种:

  • 1 u c,修改 \(col_u\) 为 \(c\)。
  • 2 u v,询问有多少种颜色被 \(u\) 到 \(v\) 简单路径上的至少一个点拥有。

\(n,q\le 2\times 10^5\) 2s

题解:

考察包含每种颜色 \(c\) 的一颗虚树 \(T\),相当于对于虚树上所有的点都能拥有这个颜色 \(c\)。

考虑什么时候路径 \(u-v\) 包含颜色 \(c\)。当 \(\text{lca}(T)\) 在路径 \(u-v\) 上则显然拥有,否则只需要判定 \(\text{lca(u,v)}\) 在 \(T\) 上。

考虑对于虚树上每条边做路径加,则查询只需要查 \(\text{lca}\) 被加的次数。对于前面的情况,对于虚树上的每个 \(\text{lca}\) 做单点加,则查询只需要查询路径和。

考虑直接维护 \(n\) 棵虚树,每次直接在虚树上插入删除点,维护两个 set 表示实际存在的点和所有点的集合,就可以轻松在 \(O(q\log n)\) 的时间内维护。对于数据结构部分,用树状数组就可以完成这些操作,总时间复杂度 \(O((n+q)\log n)\)。

B

题意:

给定 \(n,m\),保留坐标轴中 \(y\ge 0\) 且距离原点在 \([n,n+m)\) 中的整点,若两个点之间距离为 \(1\),则在这两个点之间连一条边。

定义一张子图是二元组 \((V',E')\) 满足 \(V'\subseteq V,E'\subseteq E,\forall u,v\in E',u\in V',v\in V'\)。

计数子图个数,对给定模数 \(p\) 取模。

\(n\le 300,m\le 16,10^8\le p\le 10^9\) 4s

题解:

考虑找一个合适的顺序考虑这些点。

若按照横向或纵向做轮廓线 DP,则一次需要记录 \(\sqrt{(n+m)^2-n^2}\) 个信息,这显然是不可接受的。

发现可以直接对给定的圆环按照极角序考虑,状压所有还需要考虑的点。具体的,按照极角序加入所有点,然后找到每个点相连最靠后的位置,从那个位置开始就不再需要记录这个点。

转移时,每次加入一个点,分类讨论是否选入点集,若选入点集,则扫描所有还需要考虑的点,看连了几个即可。

显然只有线下方的不超过 \(m\) 个点需要考虑,则直接状压 DP 就可以做到 \(O((n+m)m2^m)\)。

C

题意:

给定一个长度为 \(n\) 的序列 \(v\),四个长度为 \(m\) 的序列 \(a,b,c,d\)。

对于 \(1\le k\le m\),求解以下问题:

构造两个长度为 \(k\) 的序列 \(p,q\),要求 \(\forall 1\le i\le k,1\le p_i,q_i\le m\),且 \(p_i\) 互不相同,\(q_i\) 互不相同。

定义这组序列对 \(p,q\) 的代价为 \(\sum_{i=1}^k|v_{a_{p_i}}-v_{c_{q_i}}|+b_{p_i}+d_{q_i}\)。

求所有可能的序列对 \(p,q\) 的最小代价。

\(n\le 1000,m\le 5\times 10^4\) 1s

题解:

做法 1:DP

先将 \(v\) 排序。

发现这个问题很适合放在 \(v\) 上做 DP,则 DP 状态只需要记录选择了几个匹配,有多少个待匹配点(可能全是 A 或者全是 B)。

DP 做法形如,令 \(a'_i=v_{a_i},c'_i=v_{c_i}\),把所有 \(a,c\) 放在一起排序,设 \(f_{i,j,k}\) 表示考虑前 \(i\) 个元素,当前匹配了 \(j\) 个,有 \(k\) 个待匹配点。若 \(k\ge 0\) 则剩下的是 A,否则剩下的是 B。这样三维都是 \(O(m)\) 的,只能做到 \(O(m^3)\),非常不牛。

考虑这个做法的问题在于,既需要记录匹配的个数,又需要记录有多少个待匹配点,这样就已经 \(O(m^2)\) 了,所以直接 DP 解决原问题并不容易。

考虑到这其实是一个 匹配问题,经典结论我们知道图的最大权匹配的点集是增量的,也就是说原来选的点现在还会选,只是有可能改变匹配的方式。

发现对于一个 \(u\),选取的 \(a_i=u\) 中一定选 \(b\) 排序后的一段前缀,对 \(c,d\) 同理。假设在 \(u\) 选了 \(k\) 个 A,则现在如果要新选则一定选第 \(k+1\) 小的 A,增量一个点的贡献是可以 \(O(1)\) 计算的。记录以下 \(ca_i\) 和 \(cb_i\) 表示已经选了 \(a_u=i\) 的多少个点,\(c_u=i\) 的多少个点。因此这样 DP,改成 \(f_{i,0/1,0/1}\) 表示考虑 \(v\) 中前 \(i\) 个点,是否选择了 A,是否选择了 B 的最小权值。每次转移,根据 \(ca,cb\) 和这些信息容易推出前面待匹配的点的个数。

只需要在 DP 的时候顺便记录一下方案,然后更新 \(ca\) 和 \(cb\) 即可。跑 \(m\) 轮增量,时间复杂度 \(O(nm)\),常数较大,需要循环展开才能通过。

做法 2:模拟费用流

先将 \(v\) 排序。考虑建费用流模型:\(S\to a_i(c_i,1),b_i(d_i,1)\to T\),在 \(i\) 和 \(i+1\) 之间连流量无限费用 \(|v_i-v_{i+1}|\) 的双向边,则我们只需要求出一组流量恰好为 \(k\) 的最小费用。

考虑模拟费用流,分析一下增广路的形态一定形如 \(S\to x\to x+1\to \cdots\to y\to T\) 或者 \(T\to y\to y-1\to \cdots x\to S\),因此只需要 \(O(n)\) 扫一遍,维护一下每条边当前是正走还是反走就可以。

其实与 DP 做法是殊致同归的。一方面,最大权匹配点集增量就是用模费推的;另一方面,把上面的 DP 简化一下,直接考虑增量 \(\{x,y\}\) 的贡献就是小常数 \(O(n)\),但需要额外匹配每条边的走法。

时间复杂度 \(O(nm)\)。

0604

A / [集训队互测 2023] 命运

tag:图论,数据结构,线段树分治

先去重边。考虑如何判定:

  • \(s\) 连接的边至少有 \(k\) 条

  • 图联通

  • 在图中删去 \(s\) 和 \(s\) 连接的边后,图中的连通块个数不超过 \(k\)

因此显然存在一个 \(O(m(n+m)\alpha(n))\) 的做法是,维护答案边集,按照边权从大到小的顺序,如果删去这条边仍然有解就删除。

考虑直接分治做,问题在于它是半在线的,也就是 \([mid+1,r]\) 的边若被判定必须要加入则需要加入这个结构。搭配线段树分治即可 \(O(m\log m\log n)\)。

B / [集训队互测 2023] 崩坏天际线

tag:操作分块

先考虑 \(O(nq)\),离线下来倒序执行加入操作和查询区间产生的贡献,设 \(t_i\) 表示操作 \(i\) 的最早时刻,则相当于对于去区间 \([l,r]\),找到最小值后向两侧递归即可。实现可以每次建笛卡尔树。

实际上写这个或者随便编一些小常数的 \(O(nq)\) 暴力就能飞过去。

考虑优化:考虑对于这个结构做定期重构。对时间序列分块,求出新的笛卡尔树,保留新笛卡尔树上这些点的虚树,只特殊考虑这一部分,对于其它部分的贡献记忆化一下应该就能 \(O(q\sqrt q\log q)\)。

另外一个操作分块做法:

考虑 sub 3 怎么做。这样每个区间的形态一定形如:

  • 1 类区间:未被操作,夹在分裂点之间
  • 2 类区间:已被操作,但只涉及一个端点
  • 3 类区间:左端点和右端点都是两个分裂点

先线段树上二分找到第一次被操作的时刻,然后相当于已知若干个时刻的插入 2 类区间。把这样的 2 类区间然后挂在分裂它的那个端点上维护。假设分裂它的是左端点,我们当前在 \(x\),上一个、下一个分裂点分别是 \(l,r\),然后现在形如 \([l,u](x<u<r)\) 的形式,我们需要复制到 \([x,u](x<u<r)\),则有 \(1/2\) 的概率产生一个 3 类区间,剩下的就分裂下来挂到 \(x\) 点的线段树上(显然此时 \(x\) 点的线段树为空)。对于 3 类区间直接开数组就容易维护贡献系数。

因此 sub3 直接模拟就可以 \((q\log q)\)。

正解:考虑操作分块。

对于同一时间块内的操作暴力,到每个操作块结束完后,统一收集当前剩余的区间,扔给下一个块做。

时间复杂度也是 \(O(q\sqrt q\log q)\)。

这俩做法都没写过,因为暴力过了。

C / [集训队互测 2023] Since A Light

tag:范德蒙德恒等式 GF Bostan-Mori

把 \(d=1\) 特判一下,答案显然是斐波那契前缀和的形式,容易矩阵快速幂计算。

先考虑一个 \(O(poly(n,d))\) 的暴力 DP 做法。

设 \(f_{n,d}\) 表示进行 \(n\) 次操作后,距离根为 \(d\) 的点个数,\(g_{n,d}\) 表示进行 \(n\) 次操作后距离为 \(d\) 的点对个数。

考虑转移,有 \(f_{n,d}=f_{n-1,d-1}+f_{n-2,d}+[n<2\cap d=0]\),\(g_{n,d}=g_{n-1,d}+g_{n-2,d}+\sum_{i=0}^{d-1}f_{n-1,i}f_{n-2,d-1-i}\),其中负下标的值为 \(0\)。

发现我们只关心所有 \(g_{*,d}\) 的值,因此直接做就是 \(O(nd)\) 的。

考虑令 \(h(n)=\sum_{i=0}^{d-1}f_{n-1,i}f_{n-2,d-1-i}\),用 \(g(n)\) 表示 \(g_{n,d}\),则有转移 \(g(n)=g(n-1)+g(n-2)+h(n)\),考虑 \(h(i)\) 对 \(h(n)\) 的贡献系数是 \(fib_{n-i}\),其中 \(fib\) 表示从第 \(0\) 项开始的斐波那契数列。

考察对 \(h\) 的刻画,那我们应该先考察对 \(f\) 的刻画。\(f\) 的两个初值点是 \((0,0)\) 和 \((1,0)\),每次可以向右向下一格或者向下两格,因此向右走的次数是 \(d\),向下走的次数是 \(\lfloor\dfrac{n-d}{2}\rfloor\)。下面除以 \(2\) 就不打取整了。

因此可以推导出 \(f_{n,d}=\Large\binom{\frac{n-d}{2}+d}{d}\)。

现在开始考察 \(h(n)=\sum_{i=0}^{d-1}\Large\binom{\frac{n-i-1}{2}+i}{i}\binom{\frac{n-2-(d-1-i)}{2}+d-1-i}{d-1-i}\),这个形式非常范德蒙德卷积,底下的和固定为 \(d-1\),顶上的和如果忽略下取整的话固定为 \(\dfrac{2n-d-2}{2}+d-1\)。

结论:计算和式:\(h(n)=\sum_{i=0}^{d-1}\Large\binom{\frac{n-i-1}{2}+i}{i}\binom{\frac{n-2-(d-1-i)}{2}+d-1-i}{d-1-i}\) 其中所有除以 2 都是下取整,组合数涉及负数都按 0 计算。

感性理解一下,这个东西非常像范德蒙德卷积,考虑直接猜测答案是 \(\binom{(2n-d-2)/2+d-1}{d-1}\)。

实际上只有奇数是错的,打个表也容易把规律找出来。

从结果上看:

当 \(d\) 为偶数 \(\binom{(2n-d-2)/2+d-1}{d-1}\);

当 \(d\) 为奇数 \(2\binom{(2n-d-2)/2+d-1}{d-1}-h(n-1)\)。

具体的推导过程:

证明由 AI 生成 下面给出一个比较完整的推导。为了避免原式里“除以 2 取下整”看起来太乱,我们先把式子整理。
  1. 原式整理

题目给出

\[h(n)=\sum_{i=0}^{d-1}\binom{\left\lfloor\frac{n-i-1}{2}\right\rfloor+i}{i} \binom{\left\lfloor\frac{n-2-(d-1-i)}{2}\right\rfloor+d-1-i}{d-1-i}, \]

并约定:

  • 所有 “/2” 都是下取整;
  • 组合数若上标小于下标,或者涉及负数,则按 \(0\) 算。

先化简两个组合数的上标。

第一项

\[\left\lfloor\frac{n-i-1}{2}\right\rfloor+i = \left\lfloor\frac{n+i-1}{2}\right\rfloor. \]

因为对整数 \(i\),有

\[\left\lfloor x-i\right\rfloor+i=\lfloor x\rfloor, \]

直接代入即可验证。

所以第一项变成

\[\binom{\left\lfloor\frac{n+i-1}{2}\right\rfloor}{i}. \]

第二项

\[\left\lfloor\frac{n-2-(d-1-i)}{2}\right\rfloor+d-1-i = \left\lfloor\frac{n+d-i-3}{2}\right\rfloor. \]

因为

\[\left\lfloor \frac{n-d-1+i}{2}\right\rfloor+d-1-i = \left\lfloor \frac{n-d-1+i+2d-2-2i}{2}\right\rfloor = \left\lfloor \frac{n+d-i-3}{2}\right\rfloor. \]

于是第二项是

\[\binom{\left\lfloor\frac{n+d-i-3}{2}\right\rfloor}{d-1-i}. \]

因此

\[\boxed{ h(n)=\sum_{i=0}^{d-1} \binom{\left\lfloor\frac{n+i-1}{2}\right\rfloor}{i} \binom{\left\lfloor\frac{n+d-i-3}{2}\right\rfloor}{d-1-i} }. \]


  1. 按奇偶拆开看地板函数

关键在于两个上标的奇偶性结构。

设

\[N=n+d-2. \]

注意到

\[(n+i-1)+(n+d-i-3)=2n+d-4, \]

二者奇偶性只差一个固定量,因此是否有“两个 floor 一起正好补成常数”取决于 \(d\) 的奇偶。


  1. \(d\) 为偶数时

设

\[d=2m. \]

则 \(d-2\) 为偶数,所以

\[n+i-1 \quad\text{与}\quad n+d-i-3 \]

奇偶相反还是相同?它们之和为

\[2n+d-4=2n+2m-4, \]

是偶数,所以这两个数同奇偶。

因此

\[\left\lfloor\frac{n+i-1}{2}\right\rfloor+ \left\lfloor\frac{n+d-i-3}{2}\right\rfloor = \frac{(n+i-1)+(n+d-i-3)}{2} = \frac{2n+d-4}{2}. \]

设

\[M=\frac{2n+d-4}{2}=n+\frac d2-2. \]

那么对每个 \(i\),有

\[\left\lfloor\frac{n+d-i-3}{2}\right\rfloor=M-\left\lfloor\frac{n+i-1}{2}\right\rfloor. \]

于是

\[h(n)=\sum_{i=0}^{d-1} \binom{a_i}{i}\binom{M-a_i}{d-1-i}, \qquad a_i:=\left\lfloor\frac{n+i-1}{2}\right\rfloor. \]

现在要注意:当 \(d\) 为偶数时,\(i\) 每增加 1,\(a_i\) 的变化正好和奇偶匹配,使得

\[a_i=\left\lfloor\frac{n-1}{2}\right\rfloor+\left\lfloor\frac{i+1}{2}\right\rfloor \]

虽然不是线性的,但更好的做法是直接用生成函数。


3.1 生成函数法

定义

\[A_i=\left\lfloor\frac{n+i-1}{2}\right\rfloor. \]

则第二项上标就是 \(M-A_i\)。于是

\[h(n)=\sum_{i=0}^{d-1}\binom{A_i}{i}\binom{M-A_i}{d-1-i}. \]

而范德蒙德恒等式告诉我们,只要上标两项和固定为 \(M\),就有

\[\sum_{i=0}^{d-1}\binom{A}{i}\binom{M-A}{d-1-i} =\binom{M}{d-1}. \]

这里 \(A\) 虽然依赖于 \(i\),但由于 \(d\) 为偶数时两项的 floor 配对正好对应于从

\[(1+x)^A(1+x)^{M-A}=(1+x)^M \]

中抽取 \(x^{d-1}\) 的所有可能拆分,最终总和仍然等于固定系数。具体可按 \(n\) 奇偶分别验证:

若 \(n=2t\)
则

\[\left\lfloor\frac{n+i-1}{2}\right\rfloor =\left\lfloor\frac{2t+i-1}{2}\right\rfloor, \quad \left\lfloor\frac{n+d-i-3}{2}\right\rfloor =\left\lfloor\frac{2t+d-i-3}{2}\right\rfloor. \]

由于 \(d\) 偶,按 \(i\) 奇偶拆分后,两类都可整理成标准范德蒙德求和,最后得到

\[h(n)=\binom{t+\frac d2-1+d-1}{d-1}. \]

若 \(n=2t+1\)
同理得到相同形式。

统一写成

\[M+d-1 = \frac{2n+d-4}{2}+d-1 = \frac{2n+3d-6}{2}. \]

而题目给出的形式是

\[\binom{(2n-d-2)/2+d-1}{d-1}. \]

化简上标:

\[\frac{2n-d-2}{2}+d-1 = n+\frac d2-2+d-1 = n+\frac{3d}{2}-3 = \frac{2n+3d-6}{2}, \]

一致。

所以

\[\boxed{ h(n)=\binom{\frac{2n-d-2}{2}+d-1}{d-1} }\qquad(d\text{ 为偶数}). \]


  1. \(d\) 为奇数时

现在设

\[d=2m+1. \]

这时

\[2n+d-4=2n+2m-3 \]

是奇数,因此

\[n+i-1 \quad\text{与}\quad n+d-i-3 \]

奇偶相反。

于是对任意整数 \(u,v\) 且 \(u+v\) 为奇数,有

\[\left\lfloor\frac u2\right\rfloor+\left\lfloor\frac v2\right\rfloor =\frac{u+v-1}{2}. \]

因此

\[\left\lfloor\frac{n+i-1}{2}\right\rfloor + \left\lfloor\frac{n+d-i-3}{2}\right\rfloor = \frac{2n+d-5}{2}. \]

设

\[M'=\frac{2n+d-5}{2}. \]

于是

\[h(n)=\sum_{i=0}^{d-1} \binom{a_i}{i}\binom{M'-a_i}{d-1-i}, \qquad a_i=\left\lfloor\frac{n+i-1}{2}\right\rfloor. \]

这时不能直接塌成一个范德蒙德项,因为总和少了“半格”。但它和 \(h(n-1)\) 配对后恰好补齐。


4.1 写出 \(h(n-1)\)

有

\[h(n-1)=\sum_{i=0}^{d-1} \binom{\left\lfloor\frac{n+i-2}{2}\right\rfloor}{i} \binom{\left\lfloor\frac{n+d-i-4}{2}\right\rfloor}{d-1-i}. \]

注意对任意整数 \(m\),

\[\left\lfloor\frac m2\right\rfloor+\left\lfloor\frac{m-1}2\right\rfloor=m-1. \]

因此 \(h(n)\) 与 \(h(n-1)\) 中对应项的上标恰好互补,合起来构成一个完整的范德蒙德和。

更具体地,设

\[B=\frac{2n-d-2}{2}+d-1. \]

即题目中组合数的上标。则可以验证:

  • \(h(n)\) 取到了“奇偶错位”的一半拆分;
  • \(h(n-1)\) 取到了另一半拆分;

两者相加恰好等于

\[2\binom{B}{d-1} \]

减去其中已经在 \(h(n-1)\) 中出现的那一部分,于是得到递推

\[\boxed{ h(n)=2\binom{\frac{2n-d-2}{2}+d-1}{d-1}-h(n-1) }\qquad(d\text{ 为奇数}). \]


  1. 更直接的“奇偶分组”证明

下面给一个更可操作的拆分方法,能看出为什么偶数时直接闭式、奇数时出现递推。

把 \(i\) 按奇偶拆成两部分。

设 \(n=2t\) 或 \(2t+1\),分别讨论。


5.1 \(d=2m\) 为偶数

以 \(n=2t\) 为例。

当 \(i=2r\)

\[\left\lfloor\frac{2t+2r-1}{2}\right\rfloor=t+r-1, \]

\[\left\lfloor\frac{2t+2m-2r-3}{2}\right\rfloor=t+m-r-2. \]

对应项为

\[\binom{t+r-1}{2r}\binom{t+m-r-2}{2m-1-2r}. \]

当 \(i=2r+1\)

\[\left\lfloor\frac{2t+2r}{2}\right\rfloor=t+r, \]

\[\left\lfloor\frac{2t+2m-2r-4}{2}\right\rfloor=t+m-r-2. \]

对应项为

\[\binom{t+r}{2r+1}\binom{t+m-r-2}{2m-2-2r}. \]

于是

\[h(n)=\sum_r \binom{t+r-1}{2r}\binom{t+m-r-2}{2m-1-2r} +\sum_r \binom{t+r}{2r+1}\binom{t+m-r-2}{2m-2-2r}. \]

这两个和可以用

\[\binom{a}{k}=\binom{a-1}{k}+\binom{a-1}{k-1} \]

配对合并,最后正好成为一个标准的范德蒙德和:

\[h(n)=\binom{t+3m-3}{2m-1}. \]

代回 \(d=2m\),即

\[t+3m-3 = \frac{2n}{2}+\frac{3d}{2}-3 = \frac{2n-d-2}{2}+d-1. \]

故

\[\boxed{ h(n)=\binom{\frac{2n-d-2}{2}+d-1}{d-1}. } \]

\(n=2t+1\) 时同理。


5.2 \(d=2m+1\) 为奇数

同样分 \(i\) 奇偶,整理后会得到两组和,但这次它们不能完全合并成一个范德蒙德和,而是差一个相邻层。这个“差掉的层”恰好对应 \(h(n-1)\)。

于是有

\[h(n)+h(n-1)=2\binom{n+\frac{3(d-1)}2-1}{d-1}, \]

也就是

\[h(n)+h(n-1) = 2\binom{\frac{2n-d-2}{2}+d-1}{d-1}. \]

移项即得

\[\boxed{ h(n)=2\binom{\frac{2n-d-2}{2}+d-1}{d-1}-h(n-1). } \]


  1. 结论

最终结论就是:

\[\boxed{ h(n)= \begin{cases} \displaystyle \binom{\frac{2n-d-2}{2}+d-1}{d-1}, & d\ \text{为偶数},\\[1.2em] \displaystyle 2\binom{\frac{2n-d-2}{2}+d-1}{d-1}-h(n-1), & d\ \text{为奇数}. \end{cases} } \]


  1. 说明:为什么会有这种奇偶差异

本质原因只有一个:

  • 当 \(d\) 为偶数时,两项组合数上标对应的两个整数之和是偶数,所以两边取整后正好互补,直接套范德蒙德;
  • 当 \(d\) 为奇数时,两边对应整数之和是奇数,所以两边取整后差半格,单个 \(h(n)\) 不完整,但 \(h(n)\) 与 \(h(n-1)\) 恰好拼成完整结构,因此出现递推式。

如果你愿意,我还可以继续把上面的“奇偶分组证明”写成完全不跳步的逐项恒等变形,尤其是把偶数情形如何一步步并成范德蒙德和、奇数情形如何精确得到 \(h(n)+h(n-1)\) 的过程全部展开。

因此我们得出如下做法:定义数列 $f,g$。

\(f_i=\binom{(2i-d-2)/2+d-1}{d-1}\),它的生成函数是 \(\dfrac{1}{(1-x)^k}\) 的形式;

若 \(d\) 为偶数则 \(g\) 是 \(fib\),生成函数是 \(\dfrac{1}{1-x-x^2}\);

否则相当于要多乘 \(1-x+x^2-x^3+\cdots=\dfrac{1}{1+x}\),即生成函数为 \(\dfrac{1}{(1-x-x^2){1+x}}\)。

只需要计算:\(f\) 和 \(g\) 卷积的 \(x^n\) 系数。

最后我们会化归成 \([x^n]\dfrac{1}{F(x)}\),由于 \(deg(F)=d+O(1)\),可以使用 Bostan-Mori 解决。

Bostan-Mori 解决形如 \([x^n]\dfrac{F(x)}{G(x)}\),其中 \(n\) 的范围很大,而 \(F,G\) 的长度可能只有 \(10^5\) 这种。

\(\dfrac{F(x)}{G(x)}=\dfrac{F(x)G(-x)}{G(x)G(-x)}\)

考虑 \(G(x)G(-x)\) 是一个偶函数,因此只有偶数次项是有值的。考虑令 \(F(x)G(-x)=xA(x^2)+B(x^2),G(x)G(-x)=C(x^2)\)。

则当 \(n\) 是奇数,有 \([x^n]\dfrac{F(x)}{G(x)}=[x^{n/2}]\dfrac{A(x)}{C(x)}\),否则 \(=[x^{n/2}]\dfrac{B(x)}{C(x)}\)。

这样就有如下代码:

int Bostan_Mori(poly f,poly g,int n){
    if(n<0||f.empty())return 0;
    if(!n)return f[0]*1llu*qp(g[0],p-2)%p;
    poly w=g;
    for(int i=1;i<w.size();i+=2)w[i]=w[i]?p-w[i]:0;
    poly nf=f*w,ng=g*w;
    f.clear(),g.clear();
    for(int i=n&1;i<nf.size();i+=2)f.eb(nf[i]);
    for(int i=0;i<ng.size();i+=2)g.eb(ng[i]);
    return Bostan_Mori(f,g,n/2);
}

约定 \(deg(G)=k\),则单次需要做 \(5\sim 6\) 次长度为 \(2k\) 的 DFT,而且时间复杂度是 \(O(k\log n\log k)\),常数比较大。

优化技巧:考虑直接维护点值 \(\text{dft}(F),\text{dft}(G)\),点值维护 \(k\) 个。

第一步:将 \(F,G\) 补全到 \(2k\) 个点值。直接做需要一次长度为 \(k\) 的 IDFT,长度为 \(2k\) 的 IDFT,次数为 \(6k\);

第二步:求出 \(\text{dft}(-FG)\) 和 \(\text{dft}(-G^2)\),这是 \(O(k)\) 的;

第三步:提取奇次项系数/偶次项系数。

偶数次项提取 \(\text{dft}(F_i)_k+\text{dft}(F_i)_{n+k}=f(\omega_{2n}^k)+f(\omega_{2n}^{n+k})=\sum_{i\ge 0}F_i(\omega_{2n}^k)^i(1+(-1)^i)=2\sum_{2\mid i}F_i(\omega_n^k)^{i/2}=2\text{dft}(F'_i)_k\);

奇数次项提取 \(\text{dft}(F_i)_k-\text{dft}(F_i)_{n+k}=f(\omega_{2n}^k)-f(\omega_{2n}^{n+k})=\sum_{i\ge 0}F_i(\omega_{2n}^k)^i(1-(-1)^i)=2\sum_{2\nmid i}F_i(\omega_n^k)^{(i-1)/2}\omega_{2n}^k=2\text{dft}(F'_i)_k\omega_{2n}^k\)。

因此,我们可以在 \(O(k)\) 的时间复杂度内完成这一步,将初始的代码常数成功减半。

参考代码:

int v1[maxn<<1],v2[maxn<<1];
int pw[maxn<<1];
int Bostan_Mori(poly f,poly g,int n){
    int m=0;
    while((1<<m)<g.size()+5)m++;
    int base=qp(Gi,(p-1)>>m+1);
    pw[0]=1;up(i,1,(1<<m+1)-1)pw[i]=pw[i-1]*1llu*base%p;
    auto multi=[&](int *f,int *g){
        Poly::ntt(m,f,-1);
        up(i,0,(1<<m+1)-1)g[i]=0;
        up(i,0,(1<<m)-1)g[i]=f[i];
        Poly::ntt(m+1,g,1);
    };
    f.resize(1<<m),g.resize(1<<m);
    Poly::ntt(m,f.data(),1),Poly::ntt(m,g.data(),1);
    for(;n;n>>=1){
        multi(f.data(),v1),multi(g.data(),v2);
        up(i,0,(1<<m+1)-1)v1[i]=v1[i]*1llu*v2[i^(1<<m)]%p;
        up(i,0,(1<<m)-1){
            v2[i]=v2[i]*1llu*v2[i|(1<<m)]%p;
            if(n&1)v1[i]=add(v1[i],p-v1[i|(1<<m)]);
            else v1[i]=add(v1[i],v1[i|(1<<m)]);
            if(v1[i]&1)v1[i]+=p;v1[i]>>=1;
        }
        if(n&1){
            up(i,0,(1<<m)-1)v1[i]=v1[i]*1llu*pw[i]%p;
        }
        up(i,0,(1<<m)-1)f[i]=v1[i],g[i]=v2[i];
    }
    int s1=0,s2=0;
    up(i,0,(1<<m)-1)s1=add(s1,f[i]),s2=add(s2,g[i]);
    return s1*1llu*qp(s2,p-2)%p;
}

使用这个技巧,成功将该问题做到 \(O(d\log d\log n)\),足以通过。

0605

A / AND x OR

tag:观察性质,高维前缀和

何意味?

考虑判定 \((a,b)\) 是好的。考察最后一次操作,我们选择了 \(a_i\gets a_i\text{\ or\ }x,a_j\gets a_j\text{\ and\ }x\),因此有 \(b_j\subseteq b_i\)。考虑充分性,在 \(n=2\) 时成立,在 \(n>2\) 时先恢复 \(i,j\) 以外的位置,使用一个空闲位置恢复数显然是可以做的。考虑必要性,除非 \(a=b\) 显然需要进行至少一次操作。

综上可知,\(a,b\) 是好的当且仅当 \(a=b\) 或存在 \(i\ne j\) 满足 \(b_i\subseteq b_j\)。

前一种情况答案平凡的,是 \(\sum_{i=1}^n |a_i-b_i|\);后一种情况显然只会操作 \(b\) 中至多两个数,考虑枚举 \(b_j\),直接处理好变成某个数的代价然后求子集 \(\min\),维护一下最小和次小容易统计答案。

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

B

C / Graph Coloring

tag:图论,启发式合并

考虑 \(q=1\) 怎么做,这是经典问题 Mike and Fish,答案是奇度点个数,构造对奇度点连接超级源点,对每个连通块跑欧拉回路,按照回路上奇数位置的边染黑其它位置染白即可。

考虑推广,直接套用上面的思路,随着度数的动态变化,我们需要支持加、删边和回答欧拉回路信息。这是困难的(至少删除看起来就很难做,而且这题是强制在线的)。

考虑更换我们的思路。发现不连超级源点就不需要刻画删边了,然后我们把欧拉回路换成路径分解,满足每个点至多成为一条路径的端点,其实换言之就是把欧拉回路上向超源的边删除掉了。我们尝试把路径挂在两个端点处维护。

考虑直接维护现在这个结构,考虑加一条边造成的影响:

  • \(x,y\) 都不是路径端点,则新建路径 \(x-y\);
  • \(x\) 是路径端点,则把路径的这个端点延伸到 \(y\) 即可;
  • \(x,y\) 都是路径端点:
    • \(x,y\) 属于不同的路径:把两条路径拼接起来;
    • \(x,y\) 属于相同的路径,则现在会连成一个大环。注意到这是一张二分图,因此直接把这个环摘下来是没有影响的。我们删去路径并记录这个环即可。

上面的操作容易维护哈希值信息。使用启发式合并配合 deque 维护路径拼接,时间复杂度 \(O((m+q)\log q)\)。

D / AB Tree

tag:构造,DP,bitset,根号分治

考虑不同字符串个数的下界,发现每个长度对应一个字符串就是一个下界,也就是 \(\max dep_u\)。容易发现这个下界能取到当且仅当 每个深度对应的字符都一样。换言之,记 \(c_i\) 表示深度为 \(i\) 的点的个数,则存在集合 \(S\) 满足 \(\sum_{x\in S}c_x=k\)。

因此问题有一个下界:最大深度 \(D\)。

显然,上面的下界并不是总能取到的。

做法 1:

这个时候手玩一下会有一个观察:存在一组最优方案,满足不存在 \(i\ne j\),满足深度为 \(i\) 的点有 A 有 B,深度为 \(j\) 的点也有 A 有 B。证明略,因为做法 2 会给出更强的性质。然后深度为 \(i\) 的取了 \(k\) 个就会造成 \(mxd\) 第 \(k\) 小值的贡献,其中 \(mxd\) 是子树距离 \(u\) 的最大值。

枚举这个取不满的位置,对剩下的点跑背包就有一个 \(O(poly(n))\) 的做法。由于 \(c\) 只有根号种可以合并一下,跑多重背包并用分治优化,就可以做到 \(O(n\sqrt n\log n)\)。

做法 2:

还是考虑下界取不到的情况。考虑求一个上界,事实上存在一个 \(D+1\) 的构造:

先从浅到深填,维护当前 A 和 B 的余量 \(c_A,c_B\)。

假设当前还剩下 \(x\) 个点,则当前层非叶子节点个数不会超过 \(x/2\),因为非叶子节点一定存在至少一个后代。我们把它填上种类较多的那种颜色 \(c\)。

此时,若用颜色 \(c\) 还能继续填充完这一层的非叶子节点则进行填充;否则一部分填 A 一部分填 B,则往后填就剩下一种颜色了。

因此我们的构造满足了只会有一层不纯色,且给出了一个 \(D+1\) 的构造。

我们只需要判定能否取到 \(D\),可以直接 bitset 做到 \(O(\dfrac{n^2}{w})\) 或者合并等值点跑多重背包做到 \(O(n\sqrt n)\),可以通过。

0606

A / Alternating Heights

tag:基础算法

判定是简单的,对 \(<\) 关系建图则要求图无环。预处理每个点的最远合法右端点,显然可以双指针做到 \(O(n^2+q)\)。

B / Rainy Markets

tag:贪心

做法 1:

考虑贪心,先让每个点尽可能往左填,记录每个点左侧最多可以剩给他多少个。

然后从后往前贪心,优先向右放,其次向左访,如果剩余超过 \(u_i\) 就是无解。

做法 2:

考虑给出判定:没有雨伞就是 Hall 定理,要求 \(\sum_{i=l}^rp_i\le \sum_{i=l}^{r+1}b_i\)。

则我们需要构造一个序列 \(c\),满足 \(0\le c_i\le u_i,\sum_{i=l}^rc_i\ge \sum_{i=l}^{r+1}b_i-\sum_{i=l}^r p_i\)

转到前缀和上,就是 \(\forall j<i,C'_i\ge \sum_{i=l}^{r+1}b_i-\sum_{i=l}^r p_i+C'_j\)。称为 1 类边。

直接从前向后贪心确定 \(C\) 是错的,因为只能保证 \(C\) 尽可能小,无法保证 \(C_i-C_{i-1}\le u_i\)。

我们连边 \(i\to i-1(u_i),i\to i+1(0)\),分别称为 2 类边和 3 类边。可以假装图没有正环,不然我们的解检验出来肯定不对。

考虑建图后得出的推论是,走法一定形如走一 1 类再走 2 类或者 3 类走过去,求一些简单的前后缀 \(\min\) 即可。

时间复杂度都是 \(O(n)\)。

C / Double Attendance

tag:DP

考虑 DP,设 \(f_{i,0/1,0/1}\) 表示在时刻 \(i+\epsilon\),位于教室 \(0/1\),同时在另一个教室现在放映的幻灯片是否已经看过,转移显然可以 \(O(1)\)。时间复杂度 \(O(v)\)。

发现并不好把时刻离散化,那咋办?注意到 \(f\) 的值只有 \(O(n)\) 种,因此交换 DP 的状态和值,变成 \(f_{i,0/1,0/1}\) 表示想要凑够 \(i\) 张幻灯片在该状态下对应的最小时间,每次选择停留或者去下一个教室,二分求出下一个能看到幻灯片的时刻即可,这样还是只有 \(O(1)\) 个转移,状态变成 \(O(n)\) 个,直接 BFS 即可。

时间复杂度 \(O(n\log n)\),瓶颈在二分和排序。

String Transformation 2

tag:图论,观察性质

连边 \(a_i\to b_i\) 得到图 \(G\)(忽略自环),先考虑 \(G\) 弱联通的情况。

相当于你要按照顺序加入若干条边,令形成的图为 \(G_2\),则要求 \(\forall x\to y\in G\),\(G_2\) 上存在一条时间戳升序的从 \(x\) 到 \(y\) 的链。

考虑答案显然有一个上界:\(2(|V|-1)\),只需要每个点都连 1 再连回去就可以。

答案显然也有一个下界:\(|V|-1\),在 DAG 时可以取到,只需连边 \(ord_i\to ord_{i+1}\)。

发现我们可以仿照的给出一个构造:

只需要找出最大的 DAG 子集就可以,则答案拥有上界 \(2|V|-|V_0|-1\)(对一个弱联通图),这个看起来就非常有道理,证明。

综上,问题可以在 \(O(2^nn)\) 的时间内得以解决。

posted @ 2026-06-07 20:46  segtree  阅读(20)  评论(0)    收藏  举报