2025.2.13 - 2.28
Question 1. 「JOI 2025 Final T3」ミ・テレフェリコ (Mi Teleférico)
给定一张 \(N\) 个城市 \(M\) 条有向铁路的城际铁路网,每条边从 \(A_i\) 连向 \(B_i(A_i < B_i)\) 且归属于公司 \(C_i\),总共有 \(P\) 个公司。
一张 \([L,R]\) 型的通行券可以让人搭乘公司编号在 \([L,R]\) 之内的公司的铁路,只能通过通行券乘坐铁路,但是可以花钱修改通行券:
- 将一张 \([L,R]\) 型的通行券修改成 \([L',R']\) 型的通行券需要花费 \(|L - L'| + |R - R'|\) 元钱。
接下来有 \(Q\) 个旅客,第 \(i\) 个旅客初始有一张 \([L,R]\) 型通行券以及 \(X\) 元钱,请问 Ta 是否能够用这 \(X\) 元钱得到一张合适的通行券使得可以从 \(1\) 号城市到达每一个城市。
\(N,M\leq 3\times 10^5, P, X\leq 10^9, Q\leq 4\times 10^5\)
首先,让我们思考一下“可以从 \(1\) 号城市到达每一个城市”是一个什么条件。
Lemma
“可以从 \(1\) 号城市到达每一个城市”当且仅当“\(2\) 号城市到 \(N\) 号城市都有入边”。
Prove It
一座不是 \(1\) 号城市的城市没有入边,那么无论怎样你都不可能乘坐铁路到达这座城市了。
如果所有城市都有入边,假设需要到达城市 \(x\),找到达 \(x\) 的一条铁路的起点 \(s\),问题转化为要到达城市 \(s\),该步骤可以持续直至 \(x = 1\)。
证明完毕。
Use It
先将所有铁路按照所属公司的编号排序,假设固定了某个编号最小的公司 \(L\),那么实质上就可以得到一个编号最大的公司 \(R\),使得公司编号在 \(L\) 到 \(R\) 之间的公司的所属铁路满足“\(2\) 号城市到 \(N\) 号城市都有入边”,且我们只关心 \(R\) 的最小值,同时,增大 \(L\) 也只会带来 \(R\) 的增加,那么我们就可以求得 \(\mathcal{O}(M)\) 个极小的区间 \([L,R]\) 满足条件,用尺取法容易做到线性。
接下来每个询问 \([L,R]\) 相当于能否找到一个已知的可行区间 \([L',R']\) 并且修改到它不超过 \(X\) 的代价,考虑离线。
首先,区间大小是一个硬性限制,每个询问区间 \([L,R]\) 能够扩张的最大大小是 \(R - L + 1 + X\),与每个已知的极小可行区间 \([L,R]\) 按照长度升序排序。
对于每个询问区间 \([L,R]\),找到左端点 \(\ge L-X\) 中最小的那一个(此时的右端点也最小),判断其右端点是否 \(\leq R+X\) 即可,只要满足,因为长度合理,那么一定能够得到它。
时间复杂度为 \(\mathcal{O}((M+Q)\log_2 M)\)。
Question 2. 「JOI 2025 Final T4」長いだけのネクタイ 2 (Just Long Neckties 2)
给定一个长度为 \(N\) 值域为 \(M\) 的正整数序列 \(A\),选择 \(A\) 的一个子序列 \(B\) 满足 \(A\) 中相邻两个元素至少有一个被选中,对于长度为 \(L\) 的序列 \(X\),设 \(f(X)\) 如下:
- 设置一个长度为 \(k\),初始全部为 \(1\) 的序列 \(C\),然后按照 \(i = 1,2, \cdots, L\) 顺序执行如下操作:
- 找到一个 \(j(1\leq j\leq k)\) 使得 \(C_j\leq X_i\),然后将 \(C_j\) 赋值成 \(X_i\)。
- 如果找不到这么一个 \(j\),则其操作失败。
- \(f(X)\) 为令其操作不失败的最小正整数 \(k\)。
最小化 \(f(B)\) 的值,并告知该最小值。
\(N\leq 5\times 10^6, M\leq 21\)
A Nice Problem!
首先,让我们思考一下怎么判定一个序列 \(X\)(其长度为 \(L\))的 \(f(X)\) 的值,可以采用贪心算法。
- 初始 \(k = 0\),按照 \(i = 1,2, \cdots, L\) 顺序执行如下操作:
- 找到一个 \(j(1\leq j\leq k)\) 使得 \(C_j\leq X_i\) 且 \(C_j\) 最大(不要浪费更小的值,其以后可能有用)
- 找不到则令 \(k\gets k+1\),然后将 \(C_k\) 设置为 \(X_i\)。
- 如此得到的 \(k\) 就会是 \(f(X)\) 的值,感性理解其正确性。
根据上述贪心算法,我们可以发现,同一个时刻不会存在 \(j_1, j_2(j_1\ne j_2)\) 且 \(C_{j_1} = C_{j_2}\),因为上述过程中的要求是可以取等。
同时,我们也只关注每一次操作后的值,相当于是一个结尾值。
于是考虑 DP,设 \(f_{i,S}\) 表示考虑完前 \(i\) 个元素,当前序列 \(C\) 的数字集合是 \(S\) 是否可行。
考虑在 \(S\) 的状态集合新增一个元素 \(v\),找到一个最大值,改掉,加入 \(v\),于是这样的 DP 的时间复杂度为 \(\mathcal{O}(N2^M)\)。
考虑优化。思考一下,对于一个 \(S\) 我们唯一想要知道的是什么?只是 \(S\) 可行的最大的 \(i\),于是将状态改写为 \(f_S\) 表示 \(S\) 可行的最大下标 \(i\),显然的,\(S\) 内元素越多,\(i\) 越大。
转移这个 \(f_S\) 分为两步,查找当前 \(f_S\) 的能够持续扩展到的最大的 \(i\),使得 \(a_{i+1}, a_{i+2}\) 均不在 \(S\) 中出现过,以及将这个 \(S\) 加入一个新元素,即加入 \(a_{f_S + 1}\) 与 \(a_{f_S + 2}\) 转移到某个 \(S'\)。
New subproblem
对于一个长度为 \(N\) 的序列 \(A\),设 \(Q(S,p)\) 表示 \(A\) 从下标 \(p\) 开始的后缀中,不在 \(S\) 中出现的元素连续出现两次的最小下标 \(p\)。
这个问题将被询问 \(\mathcal{O}(2^M)\) 次,回答需要在线。
暴力,时间复杂度为 \(\mathcal{O}(2^MN)\),官方题解说这玩意还比较快。
...不好解决,换个形式吧。
New subproblem - changed
对于一个长度为 \(N\) 的序列 \(A\),设 \(Q(i,j,p)\) 表示 \(A\) 从下标 \(p\) 开始的后缀中,值 \(i\) 与值 \(j\) 连续出现的最小下标 \(p\)(即 \(a_p = i, a_{p+1} = j\))。
这个问题将被询问 \(\mathcal{O}(2^MM^2)\) 次,回答需要在线。
...这个就比较好解决。
二分,时间复杂度为 \(\mathcal{O}(N + 2^MM^2\log_2 N)\)。
预处理,时间复杂度为 \(\mathcal{O}(NM^2 + 2^MM^2)\)。
阈值分治,时间复杂度为 \(\mathcal{O}(N + 2^MM^2)\),可以通过,具体的:
- 设 \(B = M^2\),每 \(B\) 个元素分一个块,只在每一块开头保留原预处理的信息,每次查询时不断往后直到找到某个 \(B\) 的倍数或者已经出现两个连续的未出现的元素。
Question 3. 「JOI 2025 Final T5」郵便局 (Post Office)
给定一张 \(N\) 个点 \(N\) 条边的有向图,从点 \(i\) 连出恰好一条边且连向点 \(P_i\),现在有 \(M\) 个包裹,第 \(j\) 个包裹要从点 \(A_j\) 运送到点 \(B_j\),时刻 \(0\) 时每个包裹都在其起点处。
每个时刻,对于每个点,你都可以选择其上的至多一个包裹,将其运送到点 \(P_i\) 上,请问最后一个到达其目的地的包裹到达其目的地的最小时刻,或者告知无法达成目标。
\(N\leq 2\times 10^5\)
很容易发现这张图的结构是一张内向基环树森林,这启发我们考察树上的情况。
首先,有一个比较显然的贪心,每个时刻每个节点都选择运送离目的地最远的那一个,所以我们可以采用 \(\mathcal{O}(NM)\) 暴力,期望得分 \(12\)。
不太能注意到一个性质是:答案相当于每条边最后一次经过时间的最大值,因为每一个点的决策是独立的。
假设对于一个节点 \(y\),将要到达 \(y\) 的棋子的距离从小到大分别是 \(a_1,a_2,\cdots,a_k\),则经过这条边的最大时间是 \(\underset{1\leq i\leq k}{\max} a_i + (k-i+1)\),构造 \(a_1 = a_2 = \cdots = a_k\) 可以取到,且可以构造方案。
于是考虑线段树合并维护之,时间复杂度为 \(\mathcal{O}(N\log_2 N)\),可以解决树上问题。
在基环树上破环为链,倍长之,环上每个点的子树也需要复制,对于一个 \(A_j\to B_j\) 的运输路径,如果 \(A_j,B_j\) 不连通显然无解,如果有直接的子树关系那么直接连 \(A_j\to B_j, A_j + n\to B_j + n\),否则如果 \(B_j\) 在环上则显然 \(A_j\to B_j + n\),同时注意 \(A_j +n\) 因为连不到 \(B_j + 2n\) 了所以直接连向根。
其余与树上问题类似,直接做即可,时间复杂度为 \(\mathcal{O}(N\log_2 N)\)。
Some Conclusion
注:这里有三道题的题解。
-
一张无向连通图 \(G\) 上两点 \(u,v\) 间的必经点数量等价于 \(G\) 建立广义圆方树后 \(u,v\) 树链上的圆点数量。
-
一张无向连通图 \(G\) 上两边 \(s,t\) 间的必经点数量等价于 \(G\) 建立广义圆方树后 \(s,t\) 两端点的四种组合的树链上的圆点数量去除端点后的最大值。
-
一张无向连通图 \(G\) 上点集 \(S\) 间的必经点(即切断某点及其所有边后 \(S\) 不连通)数量等价于 \(G\) 建立广义圆方树后包含 \(S\) 的最小连通块中的圆点数量(视情况减去端点)。
Question 4. String on a Cycle
对于一个字符串 \(S\),我们称 \(S\) 是好的当且仅当将其围成环后不存在相邻的相同字符。
给定一个围成环的字符串 \(S\),对于所有 \(k\in [0,|S|)\),求出在这个环上砍去连续的 \(k\) 个字符得到的新字符串有没有可能是好的。
\(\sum |S|\leq 5\times 10^6\)
首先,倍长 \(S\) 得到 \(T\),然后将 \(T\) 中相邻的字符找出来,在每两组相邻的字符之间做,最终只需要考虑首尾不相同。
问题变为给定一个字符串 \(T\),对所有 \(k\in [2, |T| ]\) 求出是否可能选出下标距离为 \(k-1\) 的两个不相同的字符。
对于一个 \(k\),如果其不可能达成,那么一定有 \(T_1 = T_k, T_2 = T_{k+1},\cdots, T_{n-k+1} = T_n\),即 \(T\) 有一个长度为 \(n-k+1\) 的 Border,跑完 KMP 建立 fail 树后,从 \(|T|\) 开始跳 Border,直接父子关系的两个长度的 Border 之间的所有长度对应的 \(k\) 一定合法,差分维护即可。
时间复杂度为 \(\mathcal{O}(\sum |S|)\)。
Question 5. Matching on a Tree
给定一棵 \(n\) 个节点的树 \(T\),边有正长度,有 \(m\) 个红点和 \(m\) 个蓝点独立均匀生成在 \(n\) 个节点上(所以可能一个节点上有多个这样的有色点)。
共计 \(2m\) 个红蓝点的匹配满足:
- 每一个红点恰好匹配一个蓝点。
- 每一对匹配的红蓝点的距离的和是最大化的。
求每一对匹配的红蓝点的距离的和的期望,答案乘上 \(n^{2m}\) 之后对 \(P = 10^9 + 7\) 取余。
\(n,m\leq 2,500\)
“一对匹配的红蓝点的距离的和是最大化的”这个条件看起来非常有意思,那么它等价于什么呢?
Lemma
该条件的等价结论为:对于一条边,假设其一边有 \(r\) 个红点和 \(b\) 个蓝点,那么这条边一定能够被经过 \(\min(r,m-b) + \min(b,m-r)\) 次。
Prove It
假设一条边一侧有一个红点 \(A\) 和一个蓝点 \(B\),另一侧有一个红点 \(C\) 和一个蓝点 \(D\),目前匹配为 \(A\) 匹配 \(B\),且 \(C\) 匹配 \(D\),则调整为 \(A\) 匹配 \(D\) 而 \(B\) 匹配 \(C\),答案增加 \(2\) 倍的该边权值,这个操作我们称之为“调整”。
假设目前有一条边,假设其一边有 \(r\) 个红点和 \(b\) 个蓝点,这条边的经过次数 \(c < \min(r,m-b) + \min(b,m-r)\),不妨令 \(\min(r,m-b)\) 没有卡满,则存在该侧的一个红点匹配了该侧的一个蓝点,这将导致另一侧的一个蓝点匹配了另一侧的一个红点,根据“调整”操作,这个状态不优,故原命题得证。
Use It
答案乘上 \(n^{2m}\) 后要求的就是总和。
分讨 \(r+b\) 与 \(m\) 的大小关系,可得 \(\min(r,m-b) + \min(b,m-r) = \min(r+b, 2m - r - b)\),枚举 \(r+b\) 的值,对每一条边 \((u,v,w)\) 分别计算贡献,不妨令 \(u\) 是 \(v\) 的祖先,则贡献为:
其中组合数为点赋予标号,因为乘上 \(n^{2m}\) 之后相当于对 \(1\sim 2m\) 分别随机一个点得到序列,而序列区分对应下标的对应元素。
时间复杂度为 \(\mathcal{O}(nm)\)。
Question 6. Rectangle on a Field
给定一个矩形区域,长为 \(W\) 宽为 \(H\),区域内有 \(N\) 个整点 \((X_i,Y_i)\),在该矩形区域内找出一个子矩形区域满足:
- 子矩形区域的四个顶点均为整点。
- 子矩形区域的四条边均平行于坐标轴。
- 子矩形区域内部(不含边、顶点)没有给定点。
并使得该子矩形区域的面积最大化。
\(N\leq 3\times 10^5, W,H\leq 10^8\),保证整点坐标两两不同。
难以注意到以下结论:
Lemma
该子矩形区域一定穿过 \(x = \dfrac{W}{2}\) 或 \(y = \dfrac{H}{2}\)。
Prove It
显然,通过构建上下边界分别是 \(y = i+1, y = i\),或者左右边界分别是 \(x= i, x=i+1\),可以让周长达到 \(2(\max(H,W) + 1)\)。
而如果不穿过着两条线,假设刚好以这两条线为界,则周长为 \(2(\dfrac{H}{2}+\dfrac{W}{2}) = H+W\),更劣。
故原命题得证。
Use It
将 \(x,y\) 坐标翻转可以让 \(x = \dfrac{W}{2}\) 与 \(y = \dfrac{H}{2}\) 上的统计成为一个问题,这里仅考虑前者。
将所有点从上到下排序并依次扫描,固定了下边界后,随着上边界的上移,\(x = W/2\) 左边与右边的最近点会不断靠近这条线,这个可以用单调栈进行维护。
然后需要基于单调栈上的信息,查询 \(L_i + R_i - U_i\) 的最大值,其中 \(L_i,R_i\) 表示以点 \(i\) 的 \(Y\) 坐标为上界的左右界,可以通过差量加转为区间加与全局最大值查询,可以用线段树维护。
实现时注意需要先查询再加入该点信息,且该点前面一个点的纵坐标的左右界分别是 \(x=0\) 和 \(x=W\),需要注意。
时间复杂度为 \(\mathcal{O}(N\log_2 N)\)。
Question 7. 「JOIG 2025 Final T5」神経衰弱 2 (Pair Matching 2)
有 \(2N\) 张卡牌,第 \(i\) 张卡牌上的数字是 \(A_i\),保证 \(1\sim N\) 这些数字在这些卡牌上各两次。
Bitaro 决定玩一个叫做“神经衰弱”的游戏:
- 依次考虑卡牌 \(i = 1,2,\cdots, 2N\):
- Bitaro 可以决定拿起或不拿起这张卡牌。如果不拿,直接跳过;否则依次执行如下步骤。
- 如果 Bitaro 的左手或右手上有一张卡牌,手上的卡牌上的数字与 \(A_i\) 相同,则第 \(i\) 张卡牌与这张手上的卡牌同时消失,获得 \(V_{A_i}\) 分。
- Bitaro 的左手上如果有一张卡牌,把它丢掉。
- Bitaro 的右手上如果有一张卡牌,把它放进左手。
- 第 \(i\) 张卡牌如果没有在第 2 步中消失,把它放进右手。
Bitaro 想要最大化他的得分,请求出得分的最大值。
\(N\leq 4\times 10^5, 1\leq V_i\leq 10^9\)
首先,如果一张写有 \(X\) 的数字的卡牌最终没有获得 \(V_X\) 的分数,那么这张卡牌只是在占用空间,并没有什么大用处,据此得到:“一张写有数字 \(X\) 的卡牌如果被拿起,一定会得到 \(V_X\) 的分数”。
假设两张写有数字 \(X\) 的卡牌之间夹有写着数字 \(Y,Z\) 的卡牌,即 XYZX,尝试全部拿起,那么过程一定是这样的:
- 左手空着,右手拿起写有数字 \(X\) 的卡牌。
- 左手拿着写有数字 \(X\) 的卡牌,右手拿起写有数字 \(Y\) 的卡牌。
- 左手不得不丢弃写有数字 \(X\) 的卡牌,此时的卡牌上的数字为 \(Z\)。
据此可以得到:任何一对写有相同数字的卡牌之间最多选择拿起一张卡牌。
于是,拿起的卡牌的结构肯定是 XX 的形式与 XYXY 的形式,不可能是 XYZXYZ 或者 XYXZYZ 之类的形式。
考虑 DP,设 \(f_i\) 表示考虑到了前 \(i\) 张卡牌,设 \(L_i,R_i\) 分别是写有数字 \(i\) 的卡牌中,较左边的那一张的编号与较右边的那一张的编号,能够得到的最大分数,转移分三种:
- 不拿第 \(i\) 张卡牌,那么转移为 \(f_i\gets f_{i-1}\)。
- 拿 \(A_i\) 所对应的数字的卡牌,要求 \(R_{A_i} = i\),且以
XX的形式拿取,转移为 \(f_i\gets f_{L_{A_i} - 1} + V_{A_i}\)。 - 拿 \(A_i\) 所对应的数字的卡牌,要求 \(R_{A_i} = i\),且以
XYXY的形式拿取,转移为 \(f_i\gets \underset{1\leq j\leq N, L_j < L_{A_i} < R_j < i}{\max} f_{L_j - 1} + V_{A_i} + V_{j}\),其含义是将 \(A_i\) 视作Y并枚举可能的X求出最大收益。
暴力转移可以做到 \(\mathcal{O}(N^2)\) 的复杂度,期望得分 \(57\)。
瓶颈在于第三类转移,观察其转移式子,其目的是找到满足 \(L_j < L_{A_i} < R_j\) 中 \(f_{L_j - 1} + V_j\) 的最大值,按顺序扫描所以 \(< i\) 的限制直接忽略,没有则视作 \(0\),也即每遇到一个 \(R_j\),就可以为 \([L_j, R_j]\) 内的每一个 \(L_{A_i}\) 提供一个 \(f_{L_j - 1} + V_j\) 的可能收益,最终每次转移时需要求出对应的 \(L_{A_i}\) 的最大收益。总结一下:区间 checkmax,单点求值,可以用线段树维护。
综上,每次遇到一个 \(R_j\) 的时候,先在线段树上查询搞定第三类转移,然后在线段树上更新最大值即可,时间复杂度为 \(\mathcal{O}(N\log_2 N)\)。
Question 8. 「ARC134E」Modulo Nim
对于一个长度为 \(N\) 的序列 \(A\),Kaho-Chan & Suzune-Chan 将玩一个游戏:
- Kaho-Chan 先手,Suzune-Chan 后手,二人轮流做如下操作:
- 设 \(X\) 为当前序列 \(A\) 中的最大值,若 \(X=0\),当前操作者胜利;否则从 \([1,X]\) 中选择正整数 \(Y\),让序列 \(A\) 中的所有数字都对 \(Y\) 取余。
目前没有确定 \(A\),已知 \(\forall 1\leq i\leq N, 1\leq A_i\leq B_i\),给定 \(B_i\),求所有可能的 \(A\) 中 Kaho-Chan 胜利的方案数,答案对 \(P = 998244353\) 取余。
\(N\leq 200, B_i\leq 200\)
首先,显然给 \(A\) 去个重没有任何影响,于是直接令 \(A\) 的值的集合构成 \(S\),依次考虑如下情况。
- 若 \(S\) 为空集或 \(\{0\}\),显然 \(S\) 为必胜状态。
- 若 \(S\) 为 \(\{1\},\{2\}\),总是会使得 \(S\) 变为 \(\{0\}\),故 \(\{1\},\{2\}\) 为必败状态。
- 若 \(S\) 中存在奇数,取 \(Y=2\),于是 \(S\) 变为 \(\{1\}\),于是存在奇数的 \(S\) 为必胜状态。
- 若 \(S\) 中全是偶数,但不全是 \(4\) 的倍数,取 \(Y = 4\),于是 \(S\) 变为 \(\{2\}\),于是存在模 \(4\) 余 \(2\) 的 \(S\) 为必胜状态。
- 若 \(S\) 中全是 \(4\) 的倍数,取 \(Y = 3\):
- 若 \(S\) 变为 \(\{1\}, \{2\}\),则 \(S\) 为必胜状态。
- 否则,模 \(12\) 意义下 \(S\) 变为 \(\{4,8\}\),暴力跑一下可知 \(\{4,8\}\) 是必败状态,于是如果 \(S\) 不是 \(\{4,8\}\),取 \(Y = 12\)。
- 若 \(S\) 中全是 \(12\) 的倍数,此时 \(S\) 中的元素不超过 \(16\) 种(\(12\times 17 = 204 > 200\)),于是 \(2^{16}\) 枚举并搜索其结局,基于上述讨论剪枝即可。
设 \(C = 16, V = 200\),时间复杂度为 \(\mathcal{O}(2^CCV)\),可以接受。
至于计数,考虑全部方案,减去全是 \(1\) 或 \(2\) 的情况,减去出现的值的集合为 \(\{4,8\}\) 的情况,减去出现的值全是 \(12\) 的倍数且必败的情况。
时间复杂度为 \(\mathcal{O}(2^CCV + N2^CC)\)。
Question 9. [ICPC 2014 WF] Sensor Network
给定平面上 \(n\) 个整点,对 \(d = 0,1,2,\cdots,m\) 求解如下问题:
- 最多在平面上选择多少个点,使得它们之间的欧几里得距离两两不超过 \(d\)。
并对 \(d = m\) 的情况,构造一组合法的方案。
\(n\leq 100, m\leq 10^5\)
问题等价于最大团,团内最远点对的距离 \(\leq d\),枚举团内的最远点对 \(P_i,P_j\),设 \(D = dist(P_i,P_j)\),则有:

在这个面积相交区内选择出距离两两之间 \(\leq D\) 的最大团,而根据著名定理“最大团点的数量=补图中最大独立集点的数量“,转为在距离 $ > D$ 的图上选择最大独立集。
定理证明:任选原图中一个团,在补图上,这些点两两之间没有边,于是原图中一个团对应于补图中一个独立集,于是结论显然。
在这张距离 $ > D$ 的点对才连边的图上,我们可以发现一个有趣的事实,基于图片,划分区域 A 和区域 B,同区域内的两个点距离一定 \(\leq D\),于是这张图是二分图,求二分图最大独立集是简单的,总点数减去最大匹配即可。
这里的点,是异于 \(P_i,P_j\),且距离 \(P_i,P_j\) 均不超过 \(D\) 的点,在这些点中,距离 $ > D$ 的点对才连边得到这张二分图,而这张二分图用计算几何可以直接求出左右部点,但是这比较麻烦,直接染色即可。
不要忘记加上 \(P_i, P_j\) 两个点!
至于在二分图上求最大独立集,方法为:从没有被右部点匹配的左部点开始标记,这些被标记的左部点相邻的右部点全部标记,然后走到右部点匹配的左部点,最终的最大独立集为左部点中被标记的和右部点中没被标记的。
时间复杂度为 \(\mathcal{O}(n^5)\),但反正卡不满,可以通过。
Question 10. 「JOISC 2020 Day 1」建筑装饰 4
给定两个长度为 \(2N\) 的非负整数序列 \(A,B\),求一个长度为 \(2N\) 的非负整数序列 \(C\),满足:
- \(C_i\) 从 \(A_i,B_i\) 中选择一个。
- 恰好分别有 \(N\) 个 \(A_i,B_i\) 被选入 \(C\)。
- \(C\) 是单调不降的序列。
或告知无解。
\(N\leq 5\times 10^5, A_i,B_i\leq 10^9\)
首先有一个显然的 DP,设 \(f_{i,j,0/1}\) 表示考虑完前 \(i\) 个元素,有 \(j\) 个是从 \(A_i\) 中选择的,第 \(i\) 个元素选择了 \(A_i\) 还是 \(B_i\),转移是容易的。
时间复杂度为 \(\mathcal{O}(N^2)\),期望得分 \(11\)。
但是在本题中可以得到:对于任意的 \((i,0/1)\) 组,合法的 \(j\) 形如一个区间。若其成立,则设 \(f_{i,0/1}\) 表示考虑完前 \(i\) 个元素,第 \(i\) 个元素选择了 \(A_i\) 还是 \(B_i\),合法的 \(j\) 的范围,时间复杂度为 \(\mathcal{O}(N)\),期望得分 \(100\)。
证明:仅考虑 \(a_{i-1},b_{i-1}\) 均能转移到 \(i\),能够转移到 \(\min(a_{i-1},b_{i-1})\) 的一定能够转移到 \(\max(a_{i-1},b_{i-1})\),贡献差为 \(1\),将所对区间平移一格后并上自己,最终结果也一定是一格区间。
Question 11. [USACO25JAN Platinum] DFS Order
给定一张 \(N\) 个点的无向图,其中初始点 \(i\) 与点 \(j\) 之间可能有边。
花费 \(A_{i,j}\) 的代价,改变点 \(i\) 与点 \(j\) 之间边的存在性,求使得 \([1,2,3,\cdots,N]\) 变为原图的合法 DFS 序的最小代价。
\(N\leq 750, 1\leq A_{i,j}\leq 1000\)
不妨在 DFS 树上考虑这个问题(Trick),显然的是每个节点的子树编号一定是连续的,且不会有连出的边。
考虑什么边都没有,设 \(f_{l,r}\) 表示考虑完 \([l,r]\) 内的所有点,并以 \(l\) 为根,转移为 \(f_{l,r} = \underset{l\leq k < r}{\max} f_{l,k} + f_{k+1,r} + A_{i,k+1}\)。
如果初始有边存在,先强制删空,原始边加入的代价取负的,每次 DP 可能会加入一些返祖边,具体的,将 \([l,k], [k+1,r]\) 合并时只会有 \(u\in [k+1,r]\) 的 \((l,u)\) 是返祖边,于是 \(f_{l,r} = \underset{l\leq k < r}{\max} f_{l,k} + f_{k+1,r} + A_{i,k+1} + \underset{k+2\leq p\leq r}{\sum} [A_{l,p}\leq 0] A_{l,p}\),前缀和优化。
时间复杂度为 \(\mathcal{O}(N^3)\)。
Question 12. Raindrops
路上有一排 \(n\) 个水坑,当雨滴落到第 \(i\) 个水坑上时,它有可能落到 \([i-a_i,i+a_i]\) 中的任何一格水坑中,并且还可以接着弹起,注意如果不在 \([1,n]\) 范围内则说明它飞出去了。
一滴雨落入第 \(u\) 个水坑,弹入第 \(v\) 个水坑的理论最少弹起次数为 \(J(u,v)\),求 \(\min(J(u,v),J(v,u))\) 的最大值。
\(n\leq 3\times 10^5, a_i\leq n\)
首先发现这是一个 \(\min\) 的最大值,考虑二分答案。
那我们马上发现,必须的数据有 \(I_k(u)\) 表示从水坑 \(u\) 弹不超过 \(k\) 次能够弹入的水坑的区间,感性理解一下这确实是一个区间,根据以往经验我们可以得知这个可以倍增,即只需要记录 \(k\) 是 \(2\) 的幂次的答案,这个倍增我们可以用线段树进行维护,时间复杂度有 \(2\) 个 \(\log\)。
每次二分检验答案,我们需要得到每个点所走到的区间,最终合法则需要存在点对 \(u,v\) 满足 \(u < L_v\) 且 \(R_u < v\),每检验一次得到 \(L,R\) 需要的时间复杂度为 \(2\) 个 \(\log\),至于是否存在则简单维护可以做到线性,不会线性可以使用二维数点,不影响复杂度,综合一下是 \(3\) 个 \(\log\),难以通过(通过合理优化可以冲过去)。
发现每次二分检验完后多次进行倍增同一个 \(2\) 的幂次非常 sb,直接倍增答案即可,时间复杂度降为 \(2\) 个 \(\log\),即 \(\mathcal{O}(n\log_2^2 n)\)。
Funny Tasks
找出你所玩的解谜游戏,或是部分游戏中解谜小游戏,对于那些可以通过思维找出较优解的游戏,写一个程序来完成它们。
Question 13. [CF2067F] Bitwise Slides
给定一个长度为 \(n\) 的正整数序列 \(a\),初始有三个非负整数变量 \(P,Q,R\),其初始值为 \(0\)。
按照 \(i = 1,2,3,\cdots, n\) 的顺序执行操作:
- 选择 \(P,Q,R\) 中恰好一个变量,将其异或上 \(a_i\)。
要求任意时刻,\(P,Q,R\) 不能两两不同,请问合法的操作序列数量?两个操作序列不同当且仅当在至少一次操作中选择了不同的变量。
答案对 \(M = 10^9 + 7\) 取余。
\(\sum n\leq 2\times 10^5, 1\leq a_i\leq 10^9\)
记 \(\oplus\) 为按位异或,记 \(b\) 为 \(a\) 的前缀异或和序列。
显然的有:在第 \(k\) 次操作后,\(P\oplus Q\oplus R = b_k\),而 \(P,Q,R\) 不能两两不同,则说明其中有一个变量值恰好为 \(b_k\),而另两个变量值相等。
考虑 DP,设 \(f_{i,x}\) 表示考虑完前 \(i\) 次操作后,相等的变量的值为 \(x\) 的方案数,初始为 \(f_{0,0} = 1\)。
不妨钦定当前状态为 \((x,x,b_i)\),那么上一次的状态可能是 \((x\oplus a_i,x,b_i),(x,x\oplus a_i,b_i),(x,x,b_i\oplus a_i)\)。
首先观察最后一种情况,也就是 \((x,x,b_i\oplus a_i)\),因为 \(b_i\oplus a_i = b_{i-1}\),所以这个状态就是 \((x,x,b_{i-1})\),也即 \(f_{i-1,x}\) 表示的状态。
对于剩余的两种状态,也就是 \((x\oplus a_i,x,b_i)\),其中至少有一个等于 \(b_{i-1}\) 而另外两个相等,根据 \(a\) 为正整数得 \(b_{i-1}\ne b_i\),故只有可能是 \(x\oplus a_i = b_{i-1}\),也即 \(x = b_i\),或者 \(x = b_{i-1}\)。
如果 \(x = b_i\),则当前的状态是 \((b_i,b_i,b_i)\),则上一步的状态是 \((b_{i-1},b_i,b_i),(b_i,b_{i-1},b_i),(b_i,b_i,b_{i-1})\),这些状态都对应着 \(f_{i-1,x}\)。
如果 \(x = b_{i-1}\),则当前的状态是 \((b_{i-1},b_{i-1},b_i)\),有 \(3\) 种方式从 \((b_{i-1},b_{i-1},b_{i-1})\) 转移而来,有 \(2\) 种方式从 \((b_{i-1},b_i,b_i)\),故 \(f_{i,x} \gets 3 f_{i-1,b_{i-1}} + 2 f_{i-1,b_i}\)。
因为 \(b\) 的数值很大,使用 map 存储 DP 即可,时间复杂度为 \(\mathcal{O}(n\log_2 n)\)。
Question 14. [ARC100E] Or Plus Max
给定一个长度为 \(2^N\) 的正整数序列 \(A\),第 \(i(0\leq i < 2^N)\) 项的值为 \(A_i\),对 \(k = 1, 2, 3, \cdots, 2^N - 1\) 求解以下问题:
- 选择 \(0\leq i < j\leq 2^N - 1\) 且 \(i\) 与 \(j\) 的按位异或小于等于 \(k\),最大化 \(A_i + A_j\) 的值。
\(N\leq 18, A_i\leq 10^9\)
sos-DP 模板。
小于等于不好做,等于也不好做,但是包含于非常好做,这么做也不会有任何影响,因为包含于肯定是小于等于的。
考虑 \(f_S\) 表示在 \(S\) 的子集中选择两个不同的下标能够得到的最大的两个数,等价于维护最小值与次小值,先枚举转移哪一位,然后转移状态即可。
最后用前缀最大值维护答案。
时间复杂度为 \(\mathcal{O}(N2^N)\)。
Question 15. 「JOISC 2023 Day 2」议会
\(N\) 个议员将会对 \(M\) 个议案做出表决,第 \(i\) 个议员会对第 \(j\) 个议案投的票取决于布尔值 \(A_{i,j}\),为 \(1\) 赞成为 \(0\) 反对。
一个人 \(i\) 如果做了议长,TA 会选择一个人 \(j(j\ne i)\) 做副议长,剩余的 \(N - 2\) 个人中,如果对议案 \(j\) 的票大于等于初始人数的一半(下取整),则议案 \(j\) 会通过。
请问对每个议员 \(i\),在选择合适的副议长的情况下,最多通过多少议案?
\(3\leq N\leq 3\times 10^5, M\leq 20\)
设 \(K = \Big\lfloor{\dfrac{N}{2}}\Big\rfloor\),以下类 FWT-and/or 操作分别代指高维前后缀的操作。
假设在 \(N\) 个议员的时候,一个议案的赞成票数量不足 \(K\),那么无论怎么样选择议长与副议长,这个议案都不可能被通过,可以直接当厕纸用;一个议案的赞成票数量达到了 \(K+2\),那么无论怎么样选择议长与副议长,这个议案都一定会被通过,因为至多减少 \(2\) 张赞成票;一个议案的赞成票数量恰好为 \(K\),那么议长与副议长必须都反对;一个议案的赞成票数量恰好为 \(K+1\),那么议长与副议长至少一个要反对。
假定拟定的议长为 \(i\),那么考虑以下情况:
- 一个议案的原始赞成票数量为 \(K\),议员 \(i\) 对此持赞成态度,让议员 \(i\) 当议长,赞成票数量变为 \(K-1\),该议案沦为厕纸。
- 一个议案的原始赞成票数量为 \(K+1\),议员 \(i\) 对此持反对态度,让议员 \(i\) 当议长,则该议案就一定能被通过。
- 一个议案的原始赞成票数量为 \(K+1\),议员 \(i\) 对此持赞成态度,或是一个议案的原始赞成票数量为 \(K\),议员 \(i\) 对此持反对态度,要想通过这个议案,就要求副议长必须在这个议案上持反对态度。
- 我们称 \(S_i\) 表示让议员 \(i\) 当议长时要求副议长持反对态度的议案的编号构成的集合。
记 \(T_i\) 表示议员 \(i\) 持反对态度的议案构成的集合,\(B_i\) 表示只要让议员 \(i\) 当议长就能通过的议案数量,则对议员 \(i\) 的答案为 \(B_i + \underset{j\ne i}{\max} | S_i\cap T_j |\)。
在 \(\mathcal{O}(NM)\) 时间复杂度内,可以处理出 \(S_i,T_i,B_i\) 的值,目标是对每个议员 \(i\) 求出 \(\underset{j\ne i}{\max} | S_i\cap T_j |\) 的值,这个 \(j\ne i\) 之后再考虑。
设 \(C = \{X\mid \exists j\in [1,N], X\subseteq T_j\}\),即所有 \(T_j\) 的所有子集的并集,目标式转为 \(\max\{ |X|\mid X\in C, X\subseteq S_i\}\)。
先对着 \(T_j\) 做一遍类 FWT-and 的操作得到 \(C\),然后因为要考虑大小,设 \(D_{u,S}\) 表示交集合 \(S\) 大小为 \(u\) 的 \(T_j\) 数量,初始对 \(C\) 中的每一个元素 \(X\) 都有 \(D_{|X|,X} = 1\),再对着每一个 \(u\) 对 \(D\) 做一遍类 FWT-or 的操作,最后对每一个 \(S\) 枚举大小判断可行性。时间复杂度为 \(\mathcal{O}(2^MM^2 + NM)\)。
???做完了吗???
没有!因为我们还没有搞定 \(j\ne i\) 的限制,为了搞定这个限制,需要记录最大值与次大值,采用 sos-DP,则只需要在 \(T\) 推到 \(C\) 的时候记录可以推到各个子集的各两个议员的编号,然后 DP 合并的时候就取大小最大的两个议员的编号,注意 DP 合并的时候去重只能靠编号,求答案的时候只需要看一下 \(f_{S_i}\) 中的两个人哪一个不是 \(i\) 就尝试采用这个议员即可,复杂度不变。
Question 16. 「Shanghai ICPC Camp 2021 Onsite Day 2」C. Minimal Cyclic Shift
对于一个字符串 \(S\),设起始位置最靠前的字典序最小的循环移位的起始位置为 \(h(S)\)。
有 \(n\) 个字符串 \(S_i\),第 \(i\) 个字符串 \(S_i\) 的长度为 \(a_i\),目标是求出 \(h(S_1), h(S_2),\cdots, h(S_n)\)。
Bob 已经正确求出了 \(h(S_1), h(S_2),\cdots, h(S_n)\),但是递交的时候不幸输出成了 \(h(S_n), h(S_1), \cdots, h(S_{n-1})\),如果 \(S_i\) 的每个字符都是在小写字母中等概率随机,请问期望依旧保持的正确的答案的数量。
\(n\leq 10^5, a_i\leq 10^5\)
首先特判 \(n=1\) 的情况,以下钦定 \(n\ge 2\),目标期望等价于分别求 \(h(S_i) = h(S_{i\bmod n + 1})\) 的概率。
设 \(f(l,p)\) 表示长度为 \(l\) 的字符串中,对应的起始位置在 \(p\) 的字符串数量,打个表发挥惊人注意力可以发现以下三点:
- \(f(l,p)\ge f(l,p+1)\)
- 若 \(f(l,p) > f(l,p+1)\),则 \(f(l,p) = f(l,p+1) + f(p,p)\)
- 仅当 \(p\mid l\) 的时候,\(f(l,p) > f(l,p+1)\)
感性理解一下,就是如果 \(n\) 个循环移位互不相同,每个位置做起点的概率相等,否则它有一个循环节,钦定其为最小的循环节时,起点就只能等概率落在这个循环节中了。
假设两个字符串长度分别为 \(n,m\),则概率为 \(\dfrac{1}{26^{n+m}} \overset{\min(n,m)}{\underset{i=1}{\sum}} f(n,i)f(m,i)\)。
于是令 \(g(p) = f(p,p)\),并搞定值域内每个数的因数,可以在 \(\mathcal{O}(V\ln V)\) 复杂度内预处理 \(g\),单次 \(\mathcal{O}(\log_2 d(V))\) 复杂度内求解 \(f(l,p)\) 的特定值。
讲一下怎么处理 \(g(p)\),这个比较简单,设 \(t\mid p\),则 \(g(t)\) 会给 \([1,t]\) 的 \(f(p,t)\) 贡献,而 \(\overset{l}{\underset{i=1}{\sum}} f(l,i) = 26^l\),减去所有 \(g(t)t\) 再均分即可。
直接枚举计算概率,结合 \(a_i\) 全部相等的特殊性质,可以获得 \(65\) 分。
发现这个决定了对于特定 \(l\),则 \(f(l,p)\) 只有 \(d(l)\) 段不同的值,总共只有 \(\mathcal{O}(n)\) 个问题,每个问题只需要归并两个约数集合即可。
时间复杂度转为 \(\mathcal{O}(nd(V))\),可以通过。
Question 17. 「The 3rd Ucup Stage 11: Sumiyosi」D. Two Box
给定一个长度为 \(N\),值域为 \([1,M]\) 内的正整数序列 \(A\),有 \(Q\) 次单点修改,每一次修改完后,回答如下问题:
- 有一个黑箱子与一个白箱子,以及编号为 \(1\sim M\) 的 \(M\) 个球,初始所有球都在白箱子中。
- 你可以进行 \(N\) 次操作,第 \(i\) 次操作你应当:
- 选择一个球把它移到它不在的箱子当中。
- 操作后要求黑箱子中的球的编号不超过 \(A_i\)。
请问操作的方案数,答案对 \(P = 998,244,353\) 取余。两组操作不同当且仅当你某次操作选择的球的编号不同。
\(N,Q\leq 3\times 10^4, M\leq 15\)
首先可以轻松列出 DP,记 \(f_{i,S}\) 表示第 \(i\) 次操作后黑箱子中的球的编号集合为 \(S\) 的方案数,每次枚举一个球转移,时间复杂度为 \(\mathcal{O}(QN2^MM)\)。
令 \(A_i\gets M - A_i\),就相当于前 \(A_i\) 个在白箱子中,假设某个编号 \(j\),存在 \(L,R\) 满足 \(j\leq A_L, j\leq A_R\),那么在 \([L+1,R]\) 中 \(j\) 个球恰好要被操作偶数次。
考虑按照球的编号考虑问题,设 \([x^i]f(x)\) 表示在当前区间中在本球及编号比本球小的所有球选择完它们的操作回合后,剩下 \(i\) 次操作没有操作任何球(以下称该类操作为“空位”)。
先将前一个球计算完后的结果全部乘起来,得到剩下 \(k\) 个“空位”的方案数,然后决策选择哪些操作在这一次被选择。
选择偶数个,等价于 \(x^k \to x^k \underset{r\ge 0}{\sum} \dbinom{k}{2r} x^{-2r}\),接下来我们来化式子,感谢这篇Blog提供的 Trick。
求个和,得到 \(f(x)\to \dfrac{f(x+1) + f(x-1)}{2}\)。
当然,这里还有一个特殊情况,就是如果这个球没有后一个位置了,那么选奇数个还是偶数个就无所谓了,变换类似,即 \(x^k \to x^k \underset{r\ge 0}{\sum} \dbinom{k}{r} x^{-r}\)。
求个和,得到 \(f(x)\to f(x+1)\)。
我们需要的是在最后能够求出 \(f(0)\) 的值,这启发我们采用点值形式维护多项式,那么乘法运算非常简单,对应点值相乘即可,变换的含义是:要想在新一轮中得到 \(f(x)\),就需要其变换后的对应式去进行计算,比如说要想在第一层计算 \(f(4)\),就需要第零层的 \(f(3),f(5)\),然后用 \(\dfrac{f(3)+f(5)}{2}\) 作为新一轮的 \(f(4)\)。
每一次你需要计算下面区间中的所有多项式的乘积,不妨只在每一段的左端点设置真正的多项式,其余位置都采用 \(f = 1\) 的多项式,然后用线段树维护区间乘积。
每一次单点修改时,可以按照从低到高顺序枚举每一层,可能进行左端点更新的有:
- \(x\) 所在连续段的左端点,把 \(x\) 拉高/拉低时可能改变右端点。
- \(x\) 本身,把 \(x\) 拉高且 \((x-1)\) 很高的时候。
- \(x+1\) 位置,把 \(x\) 拉高可能成为一个新的右端点,拉低则消失。
其余位置不可能发生改变,于是只有 \(\mathcal{O}(m)\) 个位置发生改变,暴力修改它们的信息即可,时间复杂度为 \(\mathcal{O}((n+q)m^2\log_2 n)\)。
Question 18. 「Petrozavodsk Winter 2021. Day 6」B. Binary Search Tree
有 \(n\) 棵初始为空的 BST,以及 \(m\) 个操作,操作分两类:
1 l r x,在编号在 \([l,r]\) 范围内的每一棵 BST 中,插入一个元素 \(x\)。2 u a,在编号为 \(u\) 的 BST 中,询问在这棵 BST 上查询元素 \(a\) 经过的结点的元素总和。
\(n,m\leq 2\times 10^5, 0\leq x,a\leq 10^9\),保证每一次操作 1 l r x 的 \(x\) 互不相同。
首先,离线询问,差量维护相邻两棵 BST。
考虑怎么求解这个元素 \(a\) 经过的结点的元素总和,这颗 BST 满足一个笛卡尔树的形式,感性理解一下,如果将每一棵 BST 中序遍历一次并记录每一个操作的时间戳,值会是顺序的,那么找出这个元素 \(a\) 在值序列中的位置,向左向右分别做时间戳的后缀 min 与前缀 min,所有处于这些前后缀 min 当中的都会产生贡献。
换句话说,将值比 \(a\) 大的升序考虑,记这个 \(a\) 的时间戳为 \(t\),如果遇到某个值 \(b\) 的时间戳 \(t_0 < t\),那么 \(b\) 会产生贡献然后令 \(t\gets t_0\),比 \(a\) 小的按照降序同理。
那么这个问题,可以采用楼房重建的 Trick,只不过需要支持前后缀查询,时间复杂度为 \(\mathcal{O}(n\log_2^2 n)\)。
在这个问题中,于 \(l\) 处,加入一个“权值 \(x\) 加入一个时间戳 \(t\)”,于 \(r+1\) 处,加入一个“权值 \(x\) 去除一个时间戳 \(t\)”,先搞定所有操作,然后再搞定对应点的询问,询问时注意询问的时间戳要比有作用修改的时间戳要大,写一棵线段树+扫描线即可,时间复杂度为 \(\mathcal{O}(m\log_2 ^2 m)\),为了方便一点的话可以写离散化。
Bonus:如果这 \(n\) 棵 BST 成树状结构,并且操作 1 u v x 为路径上所有 BST 加入权值 \(x\),其实差不了太多,链差分改为树上差分,然后用线段树合并合并子树即可,实现时注意空结点用“和为 \(0\),最小值为 \(+\infty\)” 来合并信息,时间复杂度不变。
实现有难度。
Question 19. [UOJ938] 方片骑士
对于一棵树,我们定义一个操作“收缩”,记为 \(u\gets v\),其定义是:
- 若 \(u,v\) 相邻,则将所有连在 \(v\) 上的点连到 \(u\) 上,然后删掉 \(v\)。
记 \(T_k\) 表示高度为 \(k\) 的满二叉树,其中 \(T_1\) 表示一个节点的树。
给定一棵 \(n\) 个结点的树 \(T\),求最小的 \(k\),使得 \(T_k\) 可以转为给定树 \(T\)。
\(\sum n\leq 10^6\)
这个操作不区分 \(v\gets u\) 和 \(u\gets v\),我们令所有操作全部是“叶 \(\to\) 根”方向,枚举根 \(r\),考虑动态规划,设 \(f_u\) 表示以 \(u\) 为根的子树的答案。
如果 \(u\) 只有 \(v\) 一个子节点,那么 \(f_u\gets f_v + 1\)。
否则,有 \(f_u\gets \Big\lceil{\log_2\Big(\underset{v\in son(u)}{\sum} 2^{f_v}\Big)}\Big\rceil\),含义是什么:
考虑子节点 \(v\),最优情况下需要 \(2^{f_v - 1}\) 个子节点,那么总叶子结点数量为 \(\underset{v\in son(u)}{\sum} 2^{f_v - 1}\),转回高度为 $ H = \Big\lceil{\log_2\Big(\underset{v\in son(u)}{\sum} 2^{f_v - 1}\Big)}\Big\rceil + 1$,将 \(+1\) 放到求和里面去等价于原式,于是我们得到了这个下界。
考虑如下构造,设 \(T_H\),按照 \(f_v\) 降序考虑每一个子节点 \(v\),找到最前面 \(2^{f_v - 1}\) 个叶子节点,计算它们的 LCA 结点 \(L\),然后直接取以 \(L\) 为根的子树,由于每一次取叶子节点的时候都取了 \(2\) 的幂个叶子节点,所以不会浪费叶子节点,这样的构造也就不存在浪费,同时这样取可以达到下界,所以这个 DP 的转移是对的。
实际编写时,考虑使用一个二进制数组暴力进位暴力算 \(\log\) 上取整的结果即可,时间复杂度为 \(\mathcal{O}(n(n+C))\),其中 \(C\) 是二进制加法的时间复杂度,其中 \(C\) 是均摊的。
接下来,我们可以采用换根计算每一个根情况下的 \(f\),首先第一次我们可以得到 \(f_1\) 以及以 \(1\) 为根时的每一棵子树的情况,换根通用式就是将 \(u\to v\) 其中 \(v\in son(u)\),通过分类讨论可以转移得到每一个 \(f\),但是在本题中,我们可以声明一个结论:“换根时可以只换 \(f_v\) 最大的子节点,且只需要换其中任意一个”。
该结论感性理解不难,具体证明不好分析。
最终时间复杂度为 \(\mathcal{O}(nC)\),本人实现为 \(\mathcal{O}(n\log_2 n)\),使用了暴力清空二进制运算数组。
Question 20. 「JOISC 2021 Day 3」聚会 2
给定一棵 \(N\) 个结点的树,对所有 \(k\in [1,N]\) 回答如下问题:
- 设 \(S\) 是一个树上的点构成点集,记 \(v(S,u)\) 表示点 \(u\) 到 \(S\) 中各点的距离总和,设 \(T(S)\) 表示 \(u\in [1,N]\) 的 \(v(S,u)\) 的最小值,你需要选择一个大小为 \(k\) 的 \(S\),使得让 \(v(S,u) = T(S)\) 的 \(u\) 尽可能多,找出满足条件的 \(u\) 的数量的最大值。
\(N\leq 2\times 10^5\)
假设对于某个点集 \(S\),在某个 \(u\) 上取到了最小值,考虑将 \(u\) 移到一个相邻点 \(w\),考察 \(v(S,w)\) 的取值相较 \(v(S,u)\) 的变化:
- 以 \(u\) 为根,\(w\) 的子树内的所有点,距离 \(-1\)。
- 以 \(w\) 为根,\(u\) 的子树内的所有点,距离 \(+1\)。
由于我们希望 \(v(S,w)\) 接着取到最小值,那么边 \((u,w)\) 两侧应当有着相同数量的 \(S\) 中的点。
那么,得到两条性质:
- 若 \(k\) 为奇数,则这样的点唯一确定。
- 反之,让 \(v(S,u)\) 取到最小值的 \(u\) 构成一条链。
枚举链两端,时间复杂度为 \(\mathcal{O}(N^2)\),考虑优化这个过程。
首先,不妨令其中一侧的点的数量为 \(s\),那么 \(s\leq \dfrac{n}{2}\),那么此时不妨令一个重心 \(R\) 作为根节点,这样可以少一些奇奇怪怪的情况。
设 \(u,v\) 为选择的链的两端,若 \(u,v\) 之间有祖先关系,不妨令 \(v\) 是 \(u\) 的祖先,并令 \(sz_u\) 表示以 \(u\) 为根的子树的大小,\(d_u\) 表示结点 \(u\) 的深度,显然影响的 \(s\) 满足 \(s\leq sz_u\),因为这一侧的点全部要落在 \(u\) 的子树中,更新的答案为 \(d_u - d_v\),由于此时 \(sz_u \leq sz_v\) 恒成立,所以 \(v\) 的深度越小越好,那么直接令 \(v = R\) 就可以。
否则,\(u,v\) 没有祖先关系,我们需要求的是:\(sz_u\ge s, sz_v\ge s\) 时 \(dis(u,v)\) 的最大值,也就是一些点之间的直径,按照 \(sz_u\) 降序考虑每个点 \(u\),每一次我们会新增一些点,需要更新直径的长度。根据著名结论:两颗边权为正的树之间连一条正权边后的直径的两个端点,一定是原两棵树的直径共四个端点中的两个,所以每次新增一个点时直接用 LCA 求距离更新答案即可。
时间复杂度为 \(\mathcal{O}(N\log_2 N)\)。
Question 21. 「JOISC 2019 Day 3」开关游戏
给定 \(N\) 盏灯的初始状态和目标状态,求最少的操作次数使得灯从初始状态变为目标状态,操作有:
Off l r,表示将编号在 \([l,r]\) 的灯全部关闭。On l r,表示将编号在 \([l,r]\) 的灯全部开启。Toggle l r,表示将编号在 \([l,r]\) 的灯全部改变开关状态(开变关,关变开)。
\(N\leq 10^6\)
还是会被 DP 卡住……
首先我们可以注意到如下性质:
- 连续执行的两个取反操作不可能相交,否则可以不操作相交的部分,用两个不相交的
Toggle操作可以等效这两次操作。 - 如果先执行一个取反操作,然后用一个
Off操作或On操作覆盖Toggle操作的部分,那么显然可以通过一定调整将Toggle放到后面,这可能需要改变Off操作或On操作的类别。
那么这 \(N\) 盏灯的唯一操作步骤就是,先 Off 或 On,视情况再使用 Toggle。
设 \(f_{i,0/1/2}\) 表示考虑完前 \(i\) 盏灯,第 \(i\) 盏灯的状态是被 Off 掉,被 On 掉,或者不变,使得前 \(i\) 盏灯满足目标状态的最少操作次数,包括 Toggle。
那么枚举上一盏灯的状态 \(x\) 与这一盏灯的状态 \(y\),如果 \(x\ne y\) 且 \(y\) 不是不变,那么代价要加一;如果仅通过覆盖操作只能使得上一盏灯复原而这一盏灯无法复原,那么需要在这一盏灯开始新增一次 Toggle 操作,此时代价额外加一。
那么答案显然取 \(f_{n,0/1/2}\) 的最小值,初始值考虑 \(f_{1,0/1/2}\) 与 \(S_1, T_1\) 的状态,时间复杂度为 \(\mathcal{O}(N)\)。
Question 22. 「JOISC 2014 Day1」 拉面比较
给定一个长度为 \(N = 400\) 的排列 \(P\),在 \(Q = 600\) 次询问以内找出最大值与最小值的下标。
询问:给定 \(x,y\),交互库返回 \(P_x > P_y\) 是否成立。
交互库自适应。
显然可以采用打擂台的方法,此时需要的次数为 \(2\times (400 - 1) = 798\) 次。
分治一下,首先用 \(200\) 次询问将 \(P\) 中元素两两分组,较大值分一组,较小值分另一组。
然后分别在两组之间分别打擂台,需要的次数减为 \(200 + 199\times 2 = 598\) 次,可以通过。
注意:交互的时候多往分治上去思考。

浙公网安备 33010602011771号