2024 July

Question 1 - [ABC360G] Suitable Edit for LIS

给定一个长度为 \(n\) 的序列 \(A\),你可以执行如下操作恰好一次,最大化 LIS 的长度:

  • 选定一个下标 \(x\) 满足 \(1\leq x\leq n\),选定一个任意的整数 \(y\),然后将 \(A_x\) 替换为 \(y\)

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


首先,用线段树优化 DP 求出 \(f_i\) 表示以 \(A_i\) 结尾的最长 LIS 的长度,\(g_i\) 表示以 \(A_i\) 开头的最长 LIS 的长度。

如果修改没有任何作用,则答案为 \(f_i\) 的最大值。

如果尝试通过修改使得 LIS 增加 \(1\),显然不会增加更多,首先,可以将 \(A_1\)\(A_n\) 自由改动使得 LIS 可能增加 \(1\),剩余情况则相当于求 \(\underset{1\leq i < j\leq n, j-i\ge 2, A_i +1\leq A_j-1}{\max} \{f_i+g_j+1\}\)

再开一棵权值线段树,然后在 \(A_i + 1\) 处存储 \(f_i\) 的值维护即可。

Question 2 - [ABC360F] InterSections

给定 \(n\) 个区间 \(I_i = (L_i,R_i)\),称 \((l_a,r_a)\)\((l_b,r_b)\) 有交当且仅当 \(l_a < l_b < r_a < r_b\)\(l_b < l_a < r_b < r_a\),求一个区间 \((l,r)\) 使得:

  • \(0\leq l < r\leq 10^9\)
  • \((l,r)\) 与尽可能多的给定区间有交。

按照交的区间数量从大到小为第一关键字,\(l\) 从小到大为第二关键字,\(r\) 从小到大为第三关键字排序,找出第一个区间。

\(1\leq n\leq 10^5, 0\leq L_i < R_i \leq 10^9\)


首先,条件 \(l_a < l_b < r_a < r_b\)\(l_b < l_a < r_b < r_a\) 可以看作矩形,其中 \((l,r)\) 可以看作坐标。

于是直接上扫描线,相当于维护权值线段树中的最大值及其位置,同时要求做到区间加,稍微维护一下即可。

注意坐标范围。

Question 3 - [CTSC2015] 日程管理

给定一个任务集 \(T\),定义 \(f(T)\) 是合理安排完成任务得到的最大收益,任务具有结束时间与收益两个属性,\(Q\) 次操作,每次向 \(T\) 中加入或删除一个任务,每次操作后求 \(f(T)\) 的值。

  • 总共有 \(D\) 天,每一天你可以完成最多一项任务。
  • 每项任务最多只能被完成一次。
  • \(f(T)\) 表示在结束时间之前完成的所有任务的收益之和。

\(1\leq D,Q\leq 3\times 10^5\)


\(i\) 天最多完成 \(i\) 项任务,不妨记 \(G_i\) 表示 \(i-\)\(i\) 天被安排完成的任务数,则 \(G_i\) 的最小值恒非负。

由于 \(G_i\) 需要完成区间加、查询区间最小值及其最左/最右的位置,故使用线段树 \(S_1\) 维护。

加入任务 \((T,v)\)

显然,我们可以求出 \([T,D]\) 内的 \(G_i\) 的最小值 \(y\),则 \(y\ge 0\)

  • \(y > 0\)
    • 非常好处理,我们直接完成这项任务即可,然后在 \(S_1\) 上完成 \([T,n]\) 区间 \(-1\) 的操作。
  • \(y = 0\)
    • 不好处理,我们需要计算在 \([T,D]\) 中完成的任务的收益最小值 \(x\),所以需要用线段树 \(S_2\) 维护区间中任务价值最小值,叶子节点处需要使用 multiset 维护。
      • \(x \ge v\),则将这项任务丢掉即可。
      • \(x < v\),则将先前的任务丢掉,再将这个任务插入即可,并在 \(S_1\) 中完成对应的操作。

删除任务 \((T,v)\)

  • 若该任务没被完成
    • 非常好处理,这个操作就没什么用。
  • 若该任务被完成了
    • 不好处理,首先把这个任务的影响从 \(S_1,S_2\) 中丢出去,我们需要计算在 \([1,D]\) 中最右边的 \(0\) 的位置(没有则为位置 \(0\))的后面一个位置 \(p\),显然 \([p,D]\) 中没有被完成的价值最大的任务可以被加入,所以需要线段树 \(S_3\) 来维护这些没有被完成的任务。

综上,两种操作都可以使用 \(S_1,S_2,S_3\) 三棵线段树互相配合完成,时间复杂度为 \(\mathcal{O}(Q\log_2 D)\)

Question 4 - [CF1982E] Number of k-good subarrays

给定 \(n,k\),求出满足如下条件的二元组 \((l,r)\) 的数量,答案对 \(10^9+7\) 取余。

  • \(0\leq l \leq r <n\)
  • \(\forall i\in [l,r], \operatorname{popcount}(i)\leq k\)

其中 \(\operatorname{popcount}(x)\) 表示 \(x\) 在二进制下 \(1\) 的数量。


首先,让我们思考 \(\operatorname{popcount}(x)\) 组成的序列,由一个 \(0\) 开始,将整个序列元素加 \(1\) 后接在原序列之后。

\(S(n,k)\) 表示上述问题的答案,根据上述性质,记 \(h(n)\) 表示小于 \(n\) 的最大的 \(2\) 的非负整数次幂,则答案满足 \(S(n,k) = S(h(n),k) + S(n-h(n),k-1)\)

\(k=0\) 时,显然答案为 \(1\),取 \(l=r=0\) 满足。

\(n\leq 2^{k+1}\)

  • \(n < 2^{k+1}\) 时,显然任取 \(0\leq l\leq r < n\) 均满足条件。
  • \(n = 2^{k+1}\) 时,显然 \(\operatorname{popcount}(2^{k+1} - 1) = k+1\) 不满足条件,故任取 \(0\leq l\leq r < n-1\) 均满足条件。

递归上述问题即可求解,但是显然会跑得巨慢,考虑到 \(S(h(n),k)\) 仅有 \((\log_2 n)^2\) 种取值,记忆化即可。

时间复杂度大约是 \(\mathcal{O}(T\log_2 ^2 n)\),具体是多少不想分析了。

Question 5 - [THUPC 2023 决赛] 那些脑海里最珍贵的

给定战斗中的相关细节,请复原战斗实况。


读题 -> 写代码 -> 调试

请注意良好码风与命名习惯。

我的第 \(5\) 道洛谷紫模拟。

Question 6 - 重返现世

Hinata 是魔法师家族的一个孩子,这天她出去玩的时候被困在了另一个世界。

为了回家,Hinata 需要使用 \(k\) 种不同的魔法石制作法阵,魔法师将在特定地点随机生成,每一时刻生成 \(1\) 个。

\(n\) 种魔法石,生成魔法石的时候,第 \(i\) 种魔法石的生成权重为 \(p_i\),概率为 \(\dfrac{p_i}{\sum^n_{i=1} p_i}\)

问集齐 \(k\) 种不同的魔法石的期望时间。

\(1\leq k\leq n\leq 10^3, n-k\leq 10\),记 \(m = \sum^n_{i=1} p_i\),则 \(1\leq m\leq 10^4, 0\leq p_i \leq m\)


首先,记 \(S\) 是魔法石的种类的集合,根据 \(\min - \max\) 容斥,我们首先思考 \(E(\underset{x\in S}{\min} x)\)\(E(\underset{x\in S}{\max} x)\) 哪一个好求。

显然,\(E(\underset{x\in S}{\min} x)\) 的生成概率,生成 \(S\) 内的元素的概率服从几何分布,故期望是概率的倒数,则 \(E(\underset{x\in S}{\min} x) = \dfrac{m}{\underset{x\in S}{\sum} p_x}\)

接下来,根据 \(\min - \max\) 容斥的扩展定理,有:

\[E(\underset{x\in S}{\operatorname{kthmax}} x) = \underset{T\subseteq S}{\sum} (-1)^{|T|-k} \binom{|T|-1}{k-1} E(\underset{x\in T}{\min} x) = \underset{T\subseteq S}{\sum} (-1)^{|T|-k} \binom{|T|-1}{k-1} \dfrac{m}{\underset{x\in T}{\sum} p_x} \]

这个是第 \(k\) 大,故先 \(k\gets n-k+1\),此时 \(k\leq 11\)

到头了,这个并不好求,但是其分母 \(\underset{x\in T}{\sum} p_x\) 仅在 \(m\) 范围,故枚举之。

\[E(\underset{x\in S}{\operatorname{kthmax}} x) = \overset{m}{\underset{s=1}{\sum}} \dfrac{m}{s} \underset{T\subseteq S}{\sum} (-1)^{|T|-k} \binom{|T|-1}{k-1} [\underset{x\in T}{\sum} p_x = s] \]

考虑 DP,设计状态有 \(f_{i,j,l}\) 表示考虑前 \(i\) 个数,总和为 \(j\)\(k' = l\) 时的总和,设 \(S_i' = \{1,2,\cdots,i-1,i\}\),有 \(f_{i,j,l} = \underset{T\subseteq S_i'}{\sum} (-1)^{|T|-l} \binom{|T|-1}{l-1} [\underset{x\in T}{\sum} p_x = j]\)

为什么我们有 \(l\) 这一维状态呢?请看后文。

转移方法

这个 DP 看起来就相当离谱,根据组合递推式,有 \(\binom{n}{m} = \binom{n-1}{m} + \binom{n-1}{m-1}\)

对于 \(f_{i,j,l}\) 而言,有两种转移方法:其一是不选择第 \(i\) 种,则 \(f_{i,j,l}\) 加上 \(f_{i-1,j,l}\);其二是选择第 \(i\) 种,转移略显离谱,根据组合递推式,令 \(v = p_i\),有:

\[\begin{aligned} f_{i,j,l} &= \underset{T\subseteq S_i'}{\sum} (-1)^{|T|-l} \binom{|T|-1}{l-1} [\underset{x\in T}{\sum} p_x = j] \\ &= f_{i-1,j,l} + \underset{T\subseteq S_{i-1}'}{\sum} (-1)^{|T|-l} (\binom{|T|-2}{l-1} + \binom{|T|-2}{l-2}) [\underset{x\in T}{\sum} p_x = j - v] \\ &= f_{i-1,j,l} + (\underset{T\subseteq S_{i-1}'}{\sum} (-1)^{|T|-l} \binom{|T|-2}{l-1} [\underset{x\in T}{\sum} p_x = j- v]) + (\underset{T\subseteq S_{i-1}'}{\sum} (-1)^{|T|-l} \binom{|T|-2}{l-2} [\underset{x\in T}{\sum} p_x = j- v]) \\ &= f_{i-1,j,l} + ((-1)\underset{T\subseteq S_{i-1}'}{\sum} (-1)^{|T|-l-1} \binom{|T|-2}{l-1} [\underset{x\in T}{\sum} p_x = j- v]) + (\underset{T\subseteq S_{i-1}'}{\sum} (-1)^{|T|-l} \binom{|T|-2}{l-2} [\underset{x\in T}{\sum} p_x = j- v]) \\ \end{aligned} \]

思考一下,等号后面两个求和是什么含义,左边一大个求和式等价于 \(f_{i-1,j-v,l}\),右边一大个求和式等价于 \(f_{i-1,j-v,l-1}\),故转移式为:

\[f_{i,j,l} = f_{i-1,j,l} - f_{i-1,j-v,l} + f_{i-1,j-v,l-1} \]

初始值

显然,对所有 \(l=0\) 的状态,仅 \(j=0\) 可行,故初始状态为 \(f_{i,0,0}=1\),其余 \(1\leq l\leq k, 1\leq j\leq m\) 的状态可依次求得。

这里就没什么组合意义之类的,仅仅因为这样写可以适配转移。

优化方法

显然可以直接递推,由于时空复杂度此时均为 \(\mathcal{O}(nm(n-k+1))\),带上滚动数组优化即可。

Question 7 - [ROI2018] Robomarathon

\(n\) 个机器人选手在跑道上准备进行跑步比赛,\(i\) 号选手在 \(i\) 号跑道上且完成跑步的时间为 \(a_i\) 秒,但是仅部分跑道会发出起跑信号,信号以 \(1\) 秒一道向左右传输。

选手名次为跑在该选手前面的人数 \(+1\)

在所有可能信号发出状态下,请问每个选手的最好名次与最坏名次。

\(1\leq n\leq 4\times 10^5, 1\leq a_i\leq 10^9\)


最好名次

我们让 \(i\) 号选手占尽优势——只在 \(i\) 道发信号,容易发现此时取得最优名次。

那么,若 \(j\) 能跑在 \(i\) 前面,仅当 \(a_j + |i-j| < a_i\)

  • \(i < j\),则 \(a_j + j - i < a_i\),即 \(a_j + j < a_i + i\)
  • \(i > j\),则 \(a_j + i - j < a_i\),即 \(a_j - j < a_i - i\)

分别扫描,树状数组维护即可。

最坏名次

即需要求得该选手前面最多跑多少人即可。

考虑第 \(i\) 个选手(下述证明感谢 zyx 补充):

  • 如果只鸣响一个跑道的信号,假设鸣响 \(j\) 道,由对称性仅考察 \(j< i\) 时的情况,假设有一个 \(k\) 满足 \(k< j\),那么 \([1,k]\cup [j,n]\)\(i\) 的优势关系不变,而 \([k,j]\) 部分,它们的跑步时间相对提早,有更大优势,所以 \(k\) 向左移动,优势更大,\(i\) 更容易取得劣势,所以 \(k\) 应当取 \(1\),同理取 \(n\)
  • 如果鸣响多个,则不妨考虑每个点起跑时间的折线图,显然 \(i\) 应当在峰值处,否则让 \(i\) 处于峰值处更劣,记 \(i\) 的峰位于区间 \([l,r]\) 处,若有一个 \(k\) 使得将峰改为 \([l-k,r+k]\),显然 \([1,l-k]\cup [l,r]\cup [r+k,n]\) 处对 \(i\) 优势不变,考虑 \([l-k,l]\cup [r,r+k]\) 处,它们相对于 \(i\) 的跑步时间提早,则占更大优势,所以应当让 \(k\) 尽可能大。
  • 综上,仅包含三种情况:
    • 鸣响跑道 \(1\) 的信号。
    • 鸣响跑道 \(n\) 的信号。
    • 如果存在一个 \(k\) 使得 \(i-k=1\land i + k \leq n\),鸣响跑道 \(1\cup [i+k,n]\) 的信号;反之存在一个 \(k\) 使得 \(i+k=n\land i - k \geq 1\),鸣响跑道 \([1,i-k]\cup n\) 的信号。

Case 1

如果 \(j\) 能赢过 \(i\),仅当 \(a_j + j - 1 < a_i + i - 1\),即 \(a_j + j < a_i + i\)

二分求出答案。

Case 2

如果 \(j\) 能赢过 \(i\),仅当 \(a_j + n - j < a_i + n - i\),即 \(a_j - j < a_i - i\)

二分求出答案。

Case 3

发现有三段,分别是峰的左半段,峰的右半段,一段平的部分,分别用树状数组,扫描时维护并计算答案即可。

总时间复杂度为 \(\mathcal{O}(n\log_2 n)\)

Question 8 - [NOI Online #2 提高组] 游戏

给定一棵 \(2n\) 个节点的树,点 \(1\) 为根,树上有 \(n\) 个红点与 \(n\) 个蓝点,Kaho/Suzune 将进行 \(n\) 轮游戏,每一轮游戏如下:

  • Kaho 等概率选择一个未被选择的红点 \(u\),Suzune 等概率选择一个未被选择的蓝点 \(v\),如果 \(u,v\) 之间有祖先关系,则祖先点的选择方胜利,否则平局。

你需要计算:\(\forall i\in [0,n]\),求出恰好有 \(i\) 轮不是平局的方案数,答案对 \(998244353\) 取余。

\(1\leq n\leq 2.5\times 10^3\)


根据二项式反演,记答案数组为 \(f_i\),若记 \(g_i\) 表示钦定 \(i\) 局非平局的方案数,则:

\[f_k = \overset{n}{\underset{i=k}{\sum}} (-1)^{i-k}\binom{i}{k} g_i \]

则目标是 \(g_i\),考虑树上背包 DP,记 \(h_{i,j}\) 表示以 \(i\) 为根的子树中选出了 \(j\) 个【祖先-儿子】点对,转移分两种:

  1. 不选择点 \(i\),则每次加入一棵子树,暴力卷积即可。

  2. 选择点 \(i\),则在最后选择一棵没被选择过的异色子树。

利用树上背包的相关优化,时间复杂度为 \(\mathcal{O}(n^2)\)

剩余未被钦定的点可以自由组合(只考虑了钦定是一定有胜负的,未被钦定的不管),所以 \(g_i\) 额外带来 \((n-i)!\) 的系数贡献。

Question 9 - 【洛谷】能天使杯 B - 孤独(Solitude)

给定两个长度为 \(n\) 的正整数序列 \(A,B\),构造正整数序列 \(S\) 满足 \(\forall 1\leq i\leq n, (S_i=A_i)\lor (S_i=B_i)\) 总是成立。

\(S_0 = S_{n+1} = 0\),定义函数 \(t(S) = \overset{n}{\underset{i=1}{\sum}} [S_i > S_{i-1}][S_i > S_{i+1}]\),定义函数 \(d(S) = (\overset{n}{\underset{i=1}{\max}} S_i) - (\overset{n}{\underset{i=1}{\min}} S_i)\)

最大化 \(t(S)\) 之后最大化 \(d(S)\),求出最后的 \(t(S),d(S)\)

\(1\leq n\leq 5\times 10^5, 1\leq A_i,B_i\leq 10^9\)


首先考虑最大化 \(t(S)\),我们考虑 DP,记 \(f_{i,0/1,0/1}\) 表示当前考虑到第 \(i\) 位,上一位取的是 \(A_i\) 还是 \(B_i\),最后选择的两个数 \(x,y\) 是否满足 $ x < y$,则转移显然。

考虑同时最大化 \(d(S)\),我们思考 \(d(S)\) 本质上是选择 \(S\) 中两个数 \(x,y\) 并最大化 \(x-y\) 的值。

于是考虑将状态扩展为 \(f_{i,0/1,0/1,0/1,0/1}\),表示当前考虑到第 \(i\) 位,上一位取的是 \(A_i\) 还是 \(B_i\),最后选择的两个数 \(x,y\) 是否满足 $ x < y$,且选出的数中 \(x\) 是否被选出,\(y\) 是否被选出。

首先从 \(i-1\) 扩展到 \(i\),这一部分仅考虑前两个 \(0/1\) 状态。

然后用 \(i\) 扩展自身,这一部分仅考虑后两个 \(0/1\) 状态。

时间复杂度为 \(\mathcal{O}(n)\),其中 \(0/1\) 状态枚举常数为 \(48\)

Question 10 - [ARC092F] Two Faced Edges

给定有向图 \(G=(V,E)\),定义 \(\operatorname{SCC}(G)\) 表示 \(G\) 的强连通分量的数量,定义 \(R(e)\) 表示 \(e\) 的反向边。

\(\forall e\in E, G_e' = (V(G),(E(G) \setminus e) \cup R(e))\),判断 \(\operatorname{SCC}(G) = \operatorname{SCC}(G_e')\) 是否成立。

\(|V|\leq 1500, |E|\leq 10^6\)


首先,我们不妨考虑 DAG:若删去 \(e\)\(u(e)\to v(e)\) 有路径,则 \(e\to R(e)\) 有影响。

不是 DAG 的时候,首先跑一个 Tarjan 缩点,于是就会有连接不同 SCC 的边(\(1\) 类边)与 SCC 内的边(\(2\) 类边)。

对于 \(1\) 类边,依旧采用上述做法。

对于 \(2\) 类边,我们可以证明:\(e\to R(e)\) 不会增加 SCC 的数量:

  • 假设出现了新的分量,在原图中一定存在 \(v(e)\to u(e)\) 的路径,在新图中一定存在一条新的 \(u(e)\to v(e)\) 的路径,合并 SCC 可得矛盾。

如果 \(u(e)\to v(e)\) 只有这条边一种路径,则 SCC 会分裂,否则不会有变化。

考虑对于固定的出发点 \(u\),求出所有 \(u(e)=u\) 的边 \(e\) 是否满足 \(u(e)\to v(e)\) 有路径,记为 \(f_e(=0/1)\)

假设记所有 \(u(e)=u\) 的边 \(e\) 的到达点 \(v(e)\) 序列记为 \(v_1\sim v_k\),则变为是否存在 \(j\ne i\)\(v_j\to v_i\) 有路径的判定问题。

写一个 bfs,就可以完成上述判定,一次求出 \(j < i\) 的部分,一次求出 \(j > i\) 的部分。

最后用 bitset 优化即可完成,时间复杂度为 \(\mathcal{O}(\dfrac{n^3}{\omega}+m)\)


采用下述方法,在 \(\mathcal{O}(\dfrac{n}{\omega})\) 时间复杂度内遍历所有值为 \(1\) 的点:

for(int i=T._Find_first();i!=T.size();i=T._Find_next(i))
posted @ 2024-07-02 09:52  ydzr00000  阅读(29)  评论(0编辑  收藏  举报