2023.9.15 CF gym 104369 vp
The 2023 Guangdong Provincial Collegiate Programming Contest
https://codeforces.com/gym/104369

A
枚举并判断即可。
B
注意到相邻的基站中不能有完整的区间,
我们可以双指针求出最小的 \(p_i\),使得 \([p_i,i]\) 中没有完整的区间。
然后单调队列即可。
C
贪心,把最小的卖到最大的即可。
D
先把所有人放在一起,然后再把 \(b_i-a_i\) 最大的几个放到外面去。
E
考虑从前往后确定答案的每一位。
若当前已经确定了答案的前 \(i\) 位,现在确定第 \(i+1\) 位。
设这个位置填的字符是 \(ch\),那么这个位置 \(a\sim ch\) 的字符串都可以随便选择,
\((ch+1)\sim z\) 的字符串只能每个位置选一个,因为选多个的 \(lcp\) 就大于 \(ch\) 了。
我们从 \(a\sim z\) 枚举 \(ch\),若选到一个 \(ch\) 满足能选的字符串个数 \(sum\ge k\),
那么 \(k\) 减去 \(ch\) 前面的 \(sum\),再计算下一位。
在当前位置结束的条件是可以当前位每个字符都选一个,不小于 \(k\).
用字典树即可。
F
显然答案是可以二分的。
我们考虑求一个区间的所有颜色是不是都在 \(A\) 里面,
可以计算出 \(A\) 里面的颜色出现次数之和,是否等于区间的长度。
建一个线段树,每个节点维护的是一个哈希表,存的是这个节点的区间里每种颜色的出现次数。
每次询问在线段树上二分即可。
G
假设已经确定了分界点 \(k\),考虑交换哪两个数才有意义。
令 \(f(i,j)=a_i \& a_{i+1} \&... \& a_j\),我们称 \(f(1,i)\neq f(1,i-1)\) 的 \(i\),为关键点。
如果值域是 \(V\),那么前缀的,后缀的关键点分别最多只有 \(\log V\) 个。
如果交换的是两个非关键点,那么其实是没有任何的用的。
那么如果交换的是两个关键点,那么直接枚举即可,是 \(O(n\log^2V)\).
若果交换的是一个关键点和一个非关键点,钦定是选择了前缀的一个关键点 \(a_i\),
那么前缀的答案是 \(f(1,i-1)\&f(i+1,k)\&a_j\),后缀的答案是 \(f(k,n)\& a_i\).
由于 \(f(1,i-1)\) 的取值只有 \(\log V\) 种,而 \(f(i+1,k)\) 也只有 \(\log V\) 种。
所以 \(f(1,i-1)\&f(i+1,k)\) 只有 \(\log^2 V\) 种。
对于每种 \(v=a_j\),计算 \(g(v,k+1)\) 表示 \(k+1\sim n\) 里最大的 \(a_j\&v\).
H
我们考虑时间倒流,一旦一个点被确定,那其以后都不能被修改了。
首先肯定是把两个数都改成 \(2\) 是最优的,放在最前。
都改成 \(1\) 是最劣的,应放在最后。
我们就是要考虑的是改了一个 \(1\) 和一个 \(2\) 的。
把每个位置的数看成图上的一个点,把一个操作改为 \(1\) 的一个点向改为 \(2\) 的那个点连有向边。
考虑选择一条边 \(u\to v\),即令 \(a_u=1\),\(a_v=2\),
且因为 \(a_u\) 已经被设为 \(1\),其能直接或间接到达的点都可以变为 \(2\).
我们要做的是就是令 \(a_u\) 变为 \(1\) 的点尽量少。
将图强连通分量缩点时候形成的 DAG 中没有入度的分量中,选择一个 \(a_u\) 即可。
但是如果一个分量中已经有一个点被改成了 \(2\),那我们令 \(u\) 为这个点。
I
二分即可。
J
若最后序列长度 \(\ge 3\),那么 \(a\le \sqrt{x},b\le \sqrt{y}\),用双指针即可。
若序列长度为 \(2\),设最高位为 \(t\),\(t\le \sqrt{x},\sqrt{y}\)
有 \(x-ta=y-tb\),那么 \(b=\frac{y-x}{t}+a\),可以得到 \(a\) 的范围,得到后随便取一个输出。
且 \(t\) 一定是 \(y-x\) 的约数,枚举 \(t\) 即可。
若序列长度为 \(1\),则 \(x=y\) 有解。
K
搜索即可。
L
求完全图的最小生成树一般使用 Boruvka 算法
称特殊边连接的节点为特殊点,其它节点为一般点。可以发现,\(2m\) 个特殊点将一般点分成了 \((2m + 1)\) 段。
一般点和其它点的连边权值至少为 \(1\)。因此根据最小生成树的性质,
一段一般点 \(l,(l + 1), ... ,r\) 内部是从小到大依次相连的。
连接后,我们可以把图简化为 \((2m + 1)\) 个 “连续点”(每个
连续点代表连续的一段一般点)以及 \(2m\) 个特殊点的完全图。
根据 Boruvka 算法,问题变为:快速维护每个点向其它连通块连边的最小边权。
每次计算 \(f_i\) 表示点 \(i\) 左边最近的,且和它不在同一连通块的点是哪个。
同理,计算 \(g\) 表示点 \(i\) 右边最近的,且和它不在同一连通块的点是哪个。
从左到右枚举每个点。如果该点是连续点,选择 \(f_i\) 和 \(g_i\) 中距离最近的即可。
如果该点是特殊点,则需要向左 / 右枚举到第一个和它没有连边,且不在同一连通块内的点。
另外还要考虑与它相邻的所有特殊边。这一步总体是 \(O(m)\) 的。
Boruvka 算法执行 \(O(\log点数)\) 轮,因此总体复杂度为 \(O (m \log m)\)。
M
设 \(f_{i,j}\) 表示 \(i\sim j\) 之间所有顶点的直径。若 \(i>j\) 就是 \(i\sim n,1\sim j\).
初始时 \(f_{i,i+1}=dis^2(i,i+1)\),
考虑区间 dp,\(f_{i,j}=\max(f_{i+1,j},f_{i,j-1},dis^2(i,j))\),
答案就是 \(\max(f(i,j)+f(j,i))\).

浙公网安备 33010602011771号