26.07 做题记录

A. 麦田

由于限制是严格小于,那么 \(\ge 2\) 的数字连续段必定不会被删掉。换句话说任何一个数最多只会被操作一次。考虑如何去刻画一个数是否会被操作。

  • 如果这个数本身是谷底,那么会被操作到两边最大的一个。
  • 如果这个数在坡上,不妨假设 \(a_i > a_{i+1}\),它会被操作当且仅当它小于谷底右边的数,操作成那个数。如果在峰旁边需要对峰取最大值。
  • 如果这个数在峰上,那么被操作就当且仅当两侧谷底的旁边一个的最小值比它都大,操作成这两者较大的一个。

直接二维偏序太麻烦了,我们操作出来 \([1,n]\) 的答案,对 \(l,r\) 调整即可,时间复杂度 \(O(n \log n)\)。B. 分披萨

B. 分披萨

考虑对于一个确定的序列,\(c\) 肯定是唯一确定的。对于确定了 \(c\),我们发现恰好分为 \(k\) 段实际上只要最多分为 $ \ge k$ 段和最少分为 \(\le k\) 段就可以实现,基于这个考虑做 dp。

对于每个 \(c\),我们分开算最多 \(<k\) 段和最少 \(>k\) 段的序列个数,用总序列减掉这两个就是一个 \(c\) 的答案,算出所有 \(c\) 的答案后加起来就好。

考虑做 dp,先考虑最多怎么做。设 \(f_{i,j}\) 代表考虑 \([1:i]\),最多划分了 \(j\) 个段,转移枚举断点 \(k\),最少似乎转移关系到断点的下一位,还要记一维 \(x\),这样不是 \(O(n^5)\) 吗?

哦,草了,原来 \(c\) 只有 \(O(\frac{n}{k})\) 个,原来是 \(O(n^4)\),这个做法感觉和标算是同构的。

A. 黑幕

首先考虑分左右两边分开做,以下考虑左边的做法。左边肯定是要在最小化代价的情况下,使得保留下来的人尽可能小。因此可以设计区间 dp,设 \(f_{l,r}\) 代表区间 \([l,r]\) 的最小化代价即代价最小化下的人的最小编号。因为需要转移,同时也要有 \(g_{l,r}\) 代表最小化代价下的最大化编号。这样做是 \(O(n^3)\)

为了让元素可以逐个加入做 dp 来干掉区间 dp,我们维护下降子序列的形态。考虑每次加入一个数 \(x\) 对一个下降段的影响,记 \(y\) 为小于 \(x\) 且最大的那一个元素,那么决策就只有删掉 \(y\) 以下加入 \(x\) 或者不动。设 \(f_x\) 代表如果把 \(<x\) 的元素全部删掉,那么所有可能的下降段中,留存下来最小的下降段长度为 \(f_x\)。注意这个 \(f_x\) 需要强制钦定 \(x\) 在下降段里面。

首先考虑说明为什么这么做是对的,也就是说明为什么可以逐个加入,因为原来需要做区间 dp 的原因是一个区间可以经过操作来提高左端点,但是这个 dp 没有直接算答案,所以保证了正确性。

考虑怎么转移 \(f_x\),假设当前加入了 \(p_i\),我们只需要对 \(f_{p_i}\) 做转移:

  • 删掉一部分并且加入 \(p_i\),有 \(f_{p_i} = \min(f_{p_i},f_i)(i <p_i)\)
  • 直接加入 \(p_i\),并且这里要求 \(p_i\) 直接和 \(f_i(i>p_i)\) 拼起来转移,那么就要求 \(p_j=i\)\(j\) 后面没有 \(k\) 使得 \(p_k\) 还没被删掉。开一个辅助数组 \(h_i\) 代表 \(i\) 后面可以直接拼数的最小值。
  • 那么算法流程为,先 \(f_{p_i} = \min(\min_{j < p_i} f_j, \min h_j)\),这里 \(h_j\) 没有下标限制是因为小后面拼大一定不优。然后 \(f_{p_i} \to h_{p_i}\),最后把 \(j>p_i\) 的所有 \(h_j\) 全部赋值成 \(\infty\)。这个用优先队列加可删堆可以快速维护。

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

QOJ12118. Dendrology

考虑不修改怎么做,考虑把贡献拆到每个点上面,不妨以 \(1\) 为根,则一个点在最小斯坦纳树上当且仅当这个点有两个儿子有标记点或者子树外和儿子内同时存在标记点。算点不太方便,考虑算边,也就是两个方向都要有点。

也就是子树外有标记并且子树内有标记,问题变为有 \(n\) 个点,每个点为白色或黑色,求同时包含白色和黑色的区间个数,容斥后等价于求 \(\sum \frac{c(c+1)}{2}\),这里 \(c\) 为连续段长度。

考虑不带修改怎么做,不带修改的话可以一遍启发式合并做到 \(O(n \log n)\)。考虑一次修改产生的变化只会修改的边上,也就是如果我们可以快速维护出修改所在边的颜色段信息就可以快速维护修改。注意到操作总量是 \(O(n)\) 的,我们把操作信息挂在边上面,一遍就能做完,时间复杂度 \(O(n \log n)\)

P10070 [CCO 2023] Travelling Trader

首先 \(k=1,3\) 是平凡的,考虑 \(k=2\) 怎么做。假设我们在 \(u\) 刚刚染色,下一步要往 \(v\) 子树走的时候,分两种情况讨论:

  • 如果进去了就不出来了,下一步染黑 \(v\) 或者染黑 \(v\) 的一个儿子 \(w\)
  • 如果进去了还要出来,下一步染黑 \(v\) 的一个儿子 \(w\)

我们发现,对于第二种情况,从 \(v\) 子树出来的时候 \(v\) 会被染黑,也就是说只能走进去一个 \(w\) 的儿子,因为这个儿子出来的时候必定会经过 \(w\),然后只能向上走。然后在踩这个孙子之前可以把整个一阶邻域全部踩完。我们设 \(f_u\) 代表刚刚踩完 \(u\),并且马上进入 \(u\) 的儿子的子树,出来的时候会踩 \(u\) 的父亲的最大权值和,这个权值和不算 \(a_u\)。记 \(N(u,k)\) 代表 \(u\) 的第 \(k\) 阶邻域,那么有转移:

\[f_u = \max_{v \in N(u,1)} (\max_{w \in N(v,1)}f_w + \sum_{w \in N(v,1)} a_w)+ \sum_{v \in N(u,1)} a_v \]

对于情况一,我们设 \(g_u\) 代表刚刚踩完 \(u\),马上走到一个儿子的子树里面,并且不用向上走的最大权值。注意这个最大权值不算上 \(a_u\)。那么有转移:

\[g_u = \max(\max_{v_0 \in N(u,1)} g_{v_0} + \max_{v \ne v_0 \wedge v \in N(u,1)}(\max_{w \in N(v,1)}f_w + \sum_{w \in N(v,1)} a_w) + \sum_{v \in N(u,1)} a_v)\\ g_u = \max(...) \]

后面那个 ... 懒得写了,大概脑补一下就是选择一个孙子跳进去,然后类似加一下贡献。最后的答案就是 \(g_1 + a_1\)

接下来考虑 \(k=3\) 怎么做:

我们先尝试一下能不能对整棵树全遍历。假设当前踩在一个刚刚染黑的 \(u\) 上面,并且假设可以最后一步跳到 \(u\) 的儿子上面。先跳到任意孙子上面,递归到子问题,然后处理完之后把所有孙子处理完,最后跳到儿子上面,接着处理其他儿子。那似乎可以全遍历啊?那是不是做完了。难点是代码难写,所以我不写代码了。时间复杂度 \(O(n \log n)\)

QOJ5367 递增树列

由于 \(\text{lca}(p_i,p_{i+1}),\text{lca}(p_{i+1},p_{i+2})\) 都是 \(p_{i+1}\) 的祖先链上的节点,所以 \(\text{lca}(p_i,p_{i+1})\)\(\text{lca} (p_i,p_{i+1})\) 必然有祖先后代关系。我们枚举最后的 \(\text{lca} (p_{n-1},p_n)=x\),那么一定是条 \(1 \to x\) 的长为 \(m\) 的路径。

那么所有节点就被划分为 \(O(m)\) 个等价类,每个等价类有个深度权值,原题的限制就变为,相邻两个数不能属于同一个等价类,并且相邻权值的 \(\min\) 是单增的。那么排列 \(p_i\) 的顺序就相对固定了,一定是先把上面的等价类选完再选下面的。

\(u\)\(x\) 走的子树大小为 \(s_0\),其余子树大小为 \(s_{1 \sim k}\),每个子树就对应了一个等价类,设 \(f_{i,j,k}\) 代表 dp 到了 \(i\),有 \(j\) 个来自上一层的钦定,要求只能填一个数,有 \(k\) 个来自这一层的钦定,的方案数。但是这样太爆炸。注意到 \(k\) 的作用是来保证两两相邻节点不属于同一个等价类,我们改变 dp 状态,对每一层,设 \(f_{i,j}\) 代表原来的 dp 含义,对相邻颜色相同容斥,设 \(g_{i,j,k}\) 代表考虑到了 \(i\),当前选了 \(j\) 个数,钦定了 \(k\) 个连续段的容斥系数和。树形背包合并即可,准确来说这个 dp 可以从下往上做,设 \(f_{u,i}\) 代表考虑 \(u\) 的子树,\(i\) 个延后贡献。复杂度 \(O(n^4) \sim O(n^5)\)

P6684 [BalticOI 2020] 小丑 (Day1)

记录一下单栈撤销做双指针的想法。首先双栈是平凡的,但是没有办法进行信息合并。

我们拿一个栈同时存左右两个栈的信息,初始时队尾栈在下面,队首栈在上面,两个栈的方向和双栈的方向相同。加入右端点是平凡的,考虑怎么删除左端点。

首先暴力一个个弹出栈顶的极长的队首栈的元素,然后找到队尾栈的大小的 lowbit 并弹出等量元素,下面会说明一定可以连续弹出这么多个。因为 lowbit 是 \(2^k\),弹掉第一个后就是 \(2^k-1\),也就是 \(k-1\) 个更小的 lowbit,所以一定可以弹出来这么多,把这 \(2^k-1\) 个元素都弹出来,然后塞进去极长的队首栈的元素,最后塞进去这 \(2^k-1\) 个元素。分析可以知道加入栈的总次数是 \(O(n \log n)\) 的。那么这个题的复杂度就可以做到 \(O(n \log^2 n + q)\)

P12478 [集训队互测 2024] Désive

首先考虑 \(1\) 操作,首先先不考虑区间限制,考虑如果是全局怎么做。建立 01-Trie,记 \(f_u\) 代表 \(u\) 子树是否是全充满,向上合并答案的时候如果有一棵子树全充满,则答案是另一棵子树的答案加上 \(2^i\),否则是两棵子树的答案的 \(\max\)

现在考虑 \(1\) 操作怎么扩展到区间上面去,扫描线,维护每个左端点,那么加入 \(a_r\) 会对 \([lst_{a_r},r]\) 这一段区间的数据结构加入 \(a_r\) 这个数。先考虑 \(a_i\) 是排列,每次填满一个大小为 \(2^i\) 的子树,就把它的兄弟的信息给重构。则每个叶子至多只会被修改 \(n\) 次。对每个叶子维护一个分段函数,代表每个左端点的答案,那么这个分段函数只有 \(O(n)\) 段。这样做是 \(O(n^32^n)\) 的。

对每个子树考虑,只有 \(O(2^i)\) 个不同的答案,对每个答案处理出来最大左端点,然后可以和祖先的 \(O(n)\) 个节点的修改信息做归并,这样的修改次数就只有 \(O(2^i+n)\),总共是 \(O(n^22^n)\) 的。

现在考虑不是排列怎么做,对每个包含 \(a_r\) 的子树的兄弟子树考虑,这里我们不考虑每个元素的分段函数,而考虑整棵树分段函数的最大值。记 \(a_r\) 的最后一次出现位置从 \(v\) 变为了 \(v'\),那么出现在 \([v,v']\) 这个下标区间内的元素,其取满 \(a_r\) 子树的时间限制从 \(v\) 变成了它的下标。如果直接暴力做,我们可以对兄弟直接暴力找到祖先链上的贡献,这样做是 \(O(n^32^n)\) 的。但是只需要操作 \([v,v']\) 中的,那么就可以把复杂度均摊到 \(O(n^2 2^n)\)

QOJ16332 Efficient Express

我是不是上周才做过这个题啊?没有关系,重新做一遍,上次贺的题解。

考虑如果一个颜色 \(c\) 满足存在 \(i\) 使得 \(c \ge x_i \wedge lst_c \le p_i\),那么这个颜色直接不用考虑。那么只剩下两种情况使得 \(i\) 可以覆盖一个颜色 \(c\)

  • \(fst_c \le p_i \wedge c \ge x_i \wedge c \ge y_i\)。进一步我们发现这个限制可以直接改为 \(c \ge x_i \wedge c \ge y_i\)
  • \(fst_c > p_i \wedge c \ge y_i\)

对于一个 \(c\) 来说,上面两种情况至少要成立一个,考虑按 \(fst_c\) 升序做 dp。具体来说,记 \(f_{i,j}\) 代表做完了 \([1,i]\) 的区间,所有满足 \(p_k < i\)\(y_k\) 的最小值是 \(j\),的方案数。直接枚举全局的最小 \(\max(x_i,y_i)\),再给 dp 加一维 \(0/1\),时间复杂度是 \(O((n+m)k^2)\)。或者考虑容斥,看作是二维点,设 \(f_{i,j,k}\) 代表考虑到 \(i\) 这个点,所有横坐标 \(<i\)\(y\) 的最小值为 \(j\),纵坐标 \(<k\) 的位置都必须合法,也可以容斥转移。

P12486 [集训队互测 2024] 木桶效应

首先考虑 \(q=0\) 我们怎么做,直接做太难了,考虑拆一下 \(\prod \min\)\(\min(p_{j,i})\) 咋拆啊,考虑对 \(a_i \le p_{j,i}\) 的数组 \(a_i\) 计数。进一步我们考虑枚举 \(a_i\)\(p_{j,i}\) 计数,而 \(p_{j,i} \ge a_i\) 即可。

这样做的好处是每一个排列变成了独立的,设 \(f_{i,j}\) 代表考虑了值域 \([1,i]\),填了 \(j\) 列的方案数。转移枚举新加入的列数 \(k\),有转移:

\[f_{i,j+k} = \sum f_{i-1,j} \binom{n-j}{n-j-k} \]

然后考虑把 \(i\) 填进去,对于每个 \(j\),排列中有 \(j-i+1\) 个空位,那么填 \(i\)\((j-i+1)^m\) 种方案。然后 \(q=0\) 做完了,时间复杂度 \(O(n^3)\)

现在来考虑 \(q \ne 0\),我们考虑把这 \(q\) 个位置拉出来单独处理。我们设 \(f_{i,j,S}\) 代表考虑了值域 \([1,i]\),填了 \(j\) 列无限制列,填了 \(S\) 这些有限制列,考虑转移:

\[f_{i,j,S} \times \binom{n'-j}{n'-j-k} \to f_{i,j+k,S} \\ f_{i,j,S} \to f_{i,j, S \cup T} \]

然后考虑把 \(i\) 填进去,继续分为无限制行和限制行,无限制行每个排列都有 \(j-i+1+p(S)\) 个空位,而限制行如果已经确定了 \(i\) 的位置,那么方案为 \(1\),否则方案为无限制行的空位数减去 \(>i\) 的限制位置个数,总复杂度 \(O(n^3 2^q)\)

P13804 [SWERC 2023] In-order

考虑先序遍历和后序遍历会对中序遍历产生什么限制,先序遍历首先可以知道根节点,然后讨论:

  • 如果根节点左右儿子都有儿子,那么可以通过两个遍历确定出儿子值和对应区间。这部分对应的是 \(A_2 \ne B_{N-2}\)
  • 如果根节点没有左儿子,或者没有右儿子,直接进入子区间递归。这部分对应的是 \(A_2 = B_{N-2}\)

那么现在二叉树的形态差不多已经固定了,唯一的问题是有些 \(u\) 只有单儿子,可以是左儿子也可以是右儿子。注意到这个东西本质是在决策 \(u\) 是填在儿子前面还是后面,数据范围不太能 dp,考虑做数数,按二叉树顺序做 DFS,记录当前点上面还有 \(cnt\) 个待决策点,那么填这个数的中序遍历的时候,如果这个点没有被标记可以不动它,也可以把待决策点拿来填线。

考虑这个填线的过程如何处理复合转移,就是说多个指定位置要怎么填线。如果一个指定点有两个包含指定点的子树,那么左右儿子顺序确定了,可以直接分开递归下去做。否则也可以递归下去做,那么做完了,复杂度 \(O(n)\)

P9139 [THUPC 2023 初赛] 喵了个喵 II

考虑相同的四个数在序列里依次为 \(i_0,i_1,i_2,i_3\),那么这四个数的子序列划分实际上只有三种,下面用 \((i,j)\) 表示 \(i\)\(j\) 不在同一个子序列。讨论:

  • \((i_0,i_1),(i_2,i_3)\)
  • \((i_0,i_2),(i_1,i_3)\)
  • \((i_0,i_3),(i_1,i_2)\):如果这种情况合法,那么一定可以调整到前面的情况,可以不考虑。

对于两个划分 \((i_0,i_1),(i_2,i_3)\)\((j_0,j_1),(j_2,j_3)\),我们发现只要 \((i_0,i_1)\)\((j_0,j_1)\),或者 \((i_2,i_3)\)\((j_2,j_3)\) 构成包含关系就不合法。那么就成了一个 2-sat 问题。可以 cdq 优化建图,复杂度 \(O(n \log^2 n)\)

墙(wall)

拆开对每一个横坐标 \(h_0\) 算贡献,先拿总方案数,总方案数等于若干个 \(0\),若干个 \(1\),若干个 \(0/1\),求 \(0\) 的权值和,这个是简单的。现在考虑把不合法的贡献减掉,首先减掉所有柱子都 \(<h_0\) 的贡献,然后对于每个前后缀算,以后缀为例子,我们钦定后缀 \([i,n]\) 唯一一个 \(\ge h_0\) 的位置是 \(i\),然后减去后缀长度乘上方案数。

那么贡献分为三个部分,前两个部分都是容易线性做的,问题在于第三个部分。我们考虑钦定 \([i,n]\) 中的最大值为 \(H_i\),然后对后面的算贡献。一种方案的权值是 \((n-i)(H_i - \max H_j)\)。考虑把两项分开求,前面一项是平凡的,问题是后面一项。写出式子:

\[\sum_H \max(H_j)[\max(H_j) < H_i] \]

考虑枚举 \(j\),然后钦定 \(j\) 为最大值:

\[\sum_{j=i+1}^n a_j[a_j < H] \prod_{k=i+1,k \ne j}^n ([a_k < a_j] + [b_k < a_j]) + b_j[b_j < H] \prod_{k=i+1,k \ne j}^n ([a_k < b_j] + [b_k < b_j]) \]

考虑这个东西怎么求,以前半部分为例子,每次加入 \((a_i,b_i)\) 会给 \([0,b_i]\) 乘上 \(0\),给 \((b_i,a_i]\) 乘上 \(1\),给 \((a_i,mx]\) 乘上 \(2\),然后加入 \(a_j\) 作为新的即可。相当于做一个线段树区间乘法,单点修改,求区间和。时间复杂度 \(O(n \log n)\)

有理数(number)

难得批爆,感觉数论烂完了。答案在求一个 \(\prod \gcd(ac,ad-bc)\) 的形式,其中 \(\gcd(a,b)=\gcd(c,d)=1\),先看如果 \(a,c\) 都是素数怎么做:

  • \(a=c\):那么 \(\gcd(ac,ad-bc)=a\gcd(a,d-b) = a\times a^{[b \equiv d\ \bmod\ a]}\),因为 \(a\) 是素数。所以可以开个桶算一下。
  • \(a \ne c\):那么 \(\gcd(ac,ad-bc)=p\) 当且仅当 \(p \mid a \wedge p \mid c\),也就是 \(p=1\),没有意义。

答案显然对每个质因子独立,对每个质因子 \(p\) 考虑:

考虑什么时候有 \(p \mid \gcd(ac,ad-bc)\),我们发现一个必要条件是 \(p \mid a \vee p \mid c\),进一步,不妨设 \(p \mid a\),那么需要有 \(p \mid \gcd(b,c)\),由于 \(b\perp a\) 所以 \(b \perp p\),那么肯定有 \(p \mid c\),也就是说条件是 \(p \mid a \wedge p \mid c\)

现在考虑 \(p\)\(\gcd\) 中的次数,设 \(a = p^{k_1} \times a',c = p^{k_2} \times c'\),这里 \(a',c'\) 不含 \(p\) 因子,讨论:

  • \(k_1 \ne k_2\),不妨设 \(k_1 < k_2\):那么 \(\gcd(ac,ad-bc) = p^{k_1} \gcd(a'c,a'd-bcp^{-k_1})\),由于 \(a'd\) 肯定不含 \(p\) 的因子,所以说 \(p\) 的次数是 \(k_1\)
  • \(k_1 = k_2\):那么 \(\gcd(ac,ad-bc) = p^k\gcd(a'c'p^k,a'd-c'b)\),也就是我们需要找到最大的 \(k'\) 满足 \(k' \le k\),使得 \(p^{k'} \mid a'd-c'b\)。把 \(\max\) 给拆掉为每一位加,也就是统计 \(\sum_{k'}[a'd-c'b \equiv 0\bmod p^{k'}]\),也就是 \(\sum_{k'}[\frac{a'}{b} \equiv \frac{c'}{d}\bmod p^{k'}]\)。用桶是可以维护的。

那么就做完了,时间复杂度 \(O(n \times s(n))\),这里的 \(s(n)\) 是分解质因数的复杂度。

P10656 [ROI 2017] 学习轨迹 (Day 2)

我是不是做过这个题来着?

把问题放到二维平面上去看,选了第 \(i\) 行的权值为 \(x_i\),选了第 \(j\) 列的权值为 \(y_j\),对于每个相同的 \(a_{i}=b_j\),则 \((i,j)\) 成为一个关键点。目标是选择一个矩形使得权值最大并且不覆盖关键点。

首先答案肯定不小于 \(\max(\sum a_i, \sum b_i)\),我们按 \(x=\frac{\sum a_i}{2},y = \frac{\sum b_i}{2}\) 把矩形分为四个部分。显然一个矩形必定会接触到两根直线中的一根,否则必定不优。不妨考虑 \(x=k\) 的情况。

显然 \(x=k\) 上下是对称且相对独立的,以上半部分为例子,注意到 \(y\) 轴上的限制随着 \(x\) 的上限降低而放宽,具体来说,记 \(h_i\) 代表 \(i\) 这个位置的关键点的最低位置。那么选择 \(y\) 轴上的 \([l,r]\)\(x\) 的权值为 \(\min_{l \le i \le r} h_i + \min_{l \le i \le r} h'_i\),这里 \(h'_i\) 是下面一半。这个后缀 \(\min\) 的形式扫描线用脚做,时间复杂度 \(O(n \log n)\),这题咋这么弱智。

P10209 [JOI 2024 Final] 路网服务 2 / Road Service 2

考虑单组询问怎么做,首先求出来原图所有连通块,求出来这些连通块的最上面的行 \(L_i\) 与最下面的行 \(R_i\),问题变为了选一些位置把区间给串连起来。

如果区间有包含关系,除非删除后区间个数为 \(1\),否则可以直接把大的区间给删掉。那么现在有若干个区间满足左右端点升序排列。直接做 dp 感觉复杂度会和值域相关。先看看,设 \(f_i\) 代表最后一个填在 \(i\) 并且前面都合法的最小代价,考虑怎么转移到 \(j\)。首先我们数组找到包含 \(i\) 的区间的最大右端点 \(r_i\),那么 \(j\) 需要满足:

  • 不存在区间 \([L_k,R_k]\)\([i,j]\) 包含。这显然是对 \(j\) 上界的约束。
  • \(j < r_i\)

如果代价全为 \(1\),那么跳最远一定不劣。放弃 dp,考虑倍增。现在有了 \(1/2\),考虑对费用倍增,维护费用为 \(2^i\) 或者 \(2^i-1\) 的最远距离。然后做完了,时间复杂度 \(O(\sum T_i \log n)\)

线段(segment)

考虑什么时候形成树结构,首先不能有双层嵌套,更具体说是不能存在一个点有 \(\ge 3\) 个区间相交。

考虑 dp,我们按左端点升序排序,设 \(f_{i,j,k}\) 代表强制选第 \(i\) 个区间,接下来选择区间的左端点不能 \(\le j\),选了 \(k\) 个的方案数。记当前区间为 \([l,r]\) 有转移:

  • \(i'\) 的区间为 \([L,R]\) 并且 \(L>j\),有 \(f_{i,j,k} \to f_{i',\max(R,j),k+1}\),这里还需要满足 \(L < r\),那么满足条件的 \(L\) 一定是一个区间,可以前缀和优化。

那么就做完了,时间复杂度 \(O(nmk)\)

布丁(pudding)

考虑特殊性质 A 怎么做,如果 \(w\) 是质数,那么我们需要让相邻两个数的 \(\gcd\) 都不为 \(1\) 且互不相同就可以快速判断 \(w\) 处于哪个区间。

首先一个想法是 \(2^i\),但是这么做后面的区间太大了。我们想要找到一个序列,相邻两项的 \(\gcd\) 互不相同,并且尽可能平均分割质数。如果 \(Q=2\),写了个随机化,随出来最少 \(11+52\) 次,考虑继续利用 \(Q\),折半两次,差不多就能过了,跑了 \(32\) 次。

接下来考虑 Subtask 3 怎么做,\(w\) 不是质数意味着我们难以通过刚刚的方法来确定 \(w\) 的大概位置,但是划分等价类仍然感觉是对的,懒得搞了,就这样吧。

P6377 [PA 2010] Termites

首先每个两端是 \(0\) 的段都是独立的,问题变为若干个队列,每次从头取一个或者从尾巴取一个。感觉应该需要做一个什么反悔贪心状物。

考虑一个贪心策略是每次选最外面最大的那一个,这个策略只有在单谷的情况下成立,考虑如果出现了一个峰 \(a_{i-1}<a_i > a_{i+1}\),那么选择了 \(i-1\) 或者 \(i+1\) 一定会紧跟着选 \(i\)。考虑直接把这三个数压成一个新的数 \(a_{i-1} + a_{i+1}-a_i\),然后一直做直到没有峰为之。时间复杂度 \(O(n \log n)\)

P11346 [KTSC 2023 R2] 会议室 2

首先考虑最外层的策略肯定是每次删掉一个长度最小的块,如果有多个就乘上组合数。

现在考虑块内删除,删除的原则是不产生新的块。考虑倒着做,每次加入一个和之前区间并有交的区间。考虑找到一种方式来刻画加入区间的方案数,我们记 \([l_1,r_1] \sim [l_k,r_k]\) 代表 \(k\) 次并的变化,那么每次变化后就有一些区间可以解除封印被选择。记 \(v_i\)\([l_i,r_i]\) 的子区间个数,那么对于这一组方案,方案数即 \(\dfrac{(n-1)!}{\prod (n-v_i)}\)。那么设 \(f_{l,r}\) 代表区间 \([l,r]\) 的答案,时间复杂度 \(O(n^2)\)

AT_wupc2019_j Color Ball

首先显然不能有绝对众数,否则输出 \(0\),设 \(f_{i,j}\) 代表填完了 \([1,i]\) 个盒子,后面钦定了 \(j\) 个球的方案数,把所有球看成不同的颜色,最后除以阶乘。由于初始和结束一样,所以不用考虑。考虑转移:

  • 考虑填满 \(i+1\) 这个盒子,此时前面剩余 \(j\) 个球没有匹配。\(i+1\) 的盒子被前面的 \(x\) 个球填上,钦定后面 \(a_{i+1}-x\) 个球;再考虑 \(i+1\) 的球填 \(y\) 个给前面的钦定。那么有:

\[\binom{a_{i+1}}{x} \binom{j}{y} \binom{j}{x} f_{i,j} \to f_{i+1,j+a_{i+1}-x-y} \]

直接做是 \(O(n^3)\) 的,虽然可以在 atcoder 通过。这说明钦定的结构不是太好做,考虑容斥,对不合法的球的个数容斥。设 \(f_{i,j}\) 代表填完 \([1,i]\),球在原来盒子的个数有 \(j\) 个的方案数,那么有转移:

\[\binom{a_{i+1}}{x}^2 x! \times f_{i,j} \to f_{i+1,j+x} \]

那么做完了,时间复杂度 \(O(nm)\)

QOJ18107 Parentheses

考虑把括号看成折线图,要么走 \((1,1)\) 要么走 \((1,-1)\),那么操作等价于把折线一段区间对称翻转。

我们断言答案不超过 \(2\),因为可以找到折线的最低点 \(x\),翻转 \([1,x]\),那么折线全部在 \(y=0\) 上方。而对于 \(y=0\) 上方的折线,一定有调整可以调整到终点 \(=0\),中途都 \(\ge 0\)。记 \(h\) 为起点和终点的高度差,一定可以调整一段上升 \(\frac{h}{2}\),变为下降 \(\frac{h}{2}\)

首先 \(0\) 次的是平凡的,考虑什么时候是一次,我们再次断言当且仅当终点是最小值,这个画画图就能理解,然后枚举终点,等价于算起点到终点,不经过某条直线,反射容斥即可,时间复杂度 \(O(n)\)

诶我草,模数为什么不是质数。化简一下发现得到了 \(3 \times 2^n -2 \binom{n}{n/2}\)

P9312 [EGOI 2021] Lanterns / 灯笼

太难了。首先有个很平凡的 \(O(n^3)\) 的区间 dp,设 \(f_{i,j}\) 代表值域区间为 \([a_i,b_j]\) 时还需要的最小代价。这个直接转移就是三方的。

考虑怎么入手优化这个东西,直接优化是个超级无敌几把大偏序,但是我们考虑 \(i,j\) 在序列上对应的区间是通过从 \([i,j]\) 两侧扩展出 \([i_1,j_1]\) 且区间都 \(\ge a_i\),以及 \([i_2,j_2]\) 且区间都 \(\ge b_j\),然后给这两个区间取交得到。我们注意到,这个区间交随着 \(b_j\) 增大而不降。对于某个 \(i_0\),如果某个 \([i_0,j_0]\) 无法转移 \([a_0,b_0]\),那么 \(b_{j'} \le b_{j_0}\)\([i_0,j']\) 也一定无法转移。基于这个可以做一个堆优化,时间复杂度 \(O(n^2 \log n)\)

P11348 [KTSC 2023 R2] 团队建设

这个题好难啊。首先答案具有决策单调性,考虑 \(l_2=r_2\) 怎么做。我们对序列 \(1\) 建立下标线段树,对于每个节点 \([l,r]\),那么序列 \(2\)\([l,r]\) 跑决策单调性时,决策点最多只会有 \(r-l+1\) 个。

因此我们对每个节点维护一个分段函数,每次查询 \(l_2=r_2=x\) 时,在线段树上 \(O(\log n)\) 个节点上,每个节点二分出来 \(x\) 所在的段,最后所有答案取 \(\max\),就可以做到 \(O(q \log^2 n)\),更进一步,可以离线分散层叠做到 \(O(q \log n)\)。这个分段函数可以从左右儿子合并,建树代价是 \(O(n \log n)\)

接着考虑 \(l_2 \ne r_2\),继续延续我们的思路,我们记一个节点的分段函数形如 \([a_1,a_2),[a_2,a_3),...,[a_k,a_{k+1})\),考虑二分 \(l_2,r_2\) 出现的位置,那么形如 \([l_2,a_i),[a_i,a_{i+1}),...,[a_j,r_2]\),我们需要求出每一段的答案。

首先两边两个散块相当于 \(O(q \log n)\) 次 sub4 的查询,中间的所有整块可以预处理,总量是 \(O(n \log n)\) 次 sub4 的查询,因此总复杂度是 \(O((n+q) \log^3 n)\),离线分散层叠可以做到 \(O((n+q) \log^2 n)\)

posted @ 2026-07-18 15:32  nullpt3  阅读(24)  评论(0)    收藏  举报