uoj177 - 新年的腮雷

题意简述:给定 \(n\) 个正整数 \(a_1,\dots,a_n\)\(m\) 个正整数 \(b_1,\dots,b_m\),进行 \(\dfrac{n-1}{m-1}\) 次操作,每次选择 \(a\) 中的 \(m\) 个正整数 \(x_1,\dots,x_m\),删去它们,加入 \(\max\{x_i+b_i\}\),求最后得到的数的最小值。

\(n,m\leqslant 5\cdot 10^4\)\((m-1)\mid(n-1)\)\(a_i\leqslant 10^8\)\(b_i\leqslant 10^7\).

不妨二分答案并倒着做,则问题转化为:考虑一个初始只有一个元素 \(\rm mid\) 的集合 \(T\),每次操作选择一个元素 \(x\) 拆成 \(m\)\(x-b_i\),问最后能不能将集合中元素进行某种排列后有 \(\forall i\in[1,n],x_i\geqslant a_i\).

\(\{a\},\{b\}\) 从小到大排序,我们考虑拆解集合 \(T\) 元素的同时从后往前与 \(\{a\}\) 进行匹配:

  • \(\max T<\max a\),无解;
  • \(\max a\leqslant \max T<b_1+\max a\),此时即使将 \(T\) 中最大元素拆掉也不能与 \(\max a\) 匹配,所以只能用当前集合 \(T\) 中的元素,显然取大于等于 \(\max a\) 且最小的元素;
  • \(\max T\geqslant b_1+\max a\),则将 \(T\) 的最大元素拆掉不劣。

时间复杂度 \(\mathcal O(n\log n\log V)\).

[IOI2015] Towns

题意简述:这是一道交互题。有一个 "圆方树",所有叶子都是圆点,所有非叶子都是方点,且方点度数至少为 \(3\)。一共有 \(n\) 个圆点,方点数量未知。边带权。你可以询问两个圆点的距离。你需要确定:

  • 树的半径的长度。定义 \(r(C)\) 表示离点 \(C\) 距离最远的圆点的距离,那么半径定义为 \(r(C)\) 的最小值;

  • 是否存在一个 \(r(C)\) 最小的 \(C\) 使得 \(C\) 是带权重心。带权重心的每个子树都有不超过 \(⌊n/2⌋\) 个圆点。

你可以询问 \(⌈7n/2⌉\) 次。\(6 \leqslant n \leqslant 110\).

"离点 \(C\) 距离最远" 提示我们寻找直径,因为树上一个点的最远点一定是直径的某个端点。采用两遍搜索寻找直径的方法(不妨设最初随机的点为 \(c\)\(c\) 找到的直径端点为 \(a\),另一个直径端点为 \(b\)),可以用 \(2n-2\) 次询问找到直径,\(a,c\) 与所有点的距离。

由于 \(r(C)\) 一定是 \(C\) 和直径端点距离的最大值,所以我们实际上只需要确定 \(C\) 与直径的距离 \(d\)\(C\) 走到直径的第一个点 \(C'\) 在直径上的位置(不妨设 \(C'\)\(a\) 的距离为 \(s\),到 \(b\) 的距离为 \(t\)),那么可以列出方程

\[s+t=\text{dis}(a,b)\\d+s=\text{dis}(a,C)\\d+t=\text{dis}(b,C) \]

由此可以解出 \(d,s,t\),我们也就找到了半径。

容易发现,\(r(C)\) 最小的点一定是直径中点,而直径中点个数至多为 \(2\),我们依次判断中点是否能成为带权重心……吗?实际上,这两个点 只可能有一个点是带权重心!不妨设这两个点为 \(u,v\)\(u\) 是离 \(a\) 更近的点。将所有 \(s\leqslant s_u\) 的点个数记为 \(\rm cnt\),容易发现 \(t\leqslant t_v\) 的点个数为 \(n-\rm cnt\)。当 \(\text{cnt}<n-\rm cnt\) 时,\(u\)\(v\) 侧子树已经大于 \(⌊n/2⌋\),反之同理。

一个很妙的转化是,考虑以 \(u\) 为根,如果存在超过 \(⌊n/2⌋\) 个点在 \(u\) 的同一个子树中,\(u\) 就不是带权重心。"\(⌊n/2⌋\)","同一个子树"……这实际上可以转化成主元素问题!这个问题有一个经典的空间 \(\mathcal O(1)\),时间 \(\mathcal O(n)\) 的做法,可以去 \(\text{oi-wiki}\) 上看。如何判断两个点是否在同一子树呢?由于直径中点在直径上(这不是废话吗?),所以可以利用每个点之前求的 \(s,t,d\) 来算出每个点到直径中点的距离 \(D\):若 \(u,v\) 在同一子树,那么有 \(D(u)+D(v)>\text{dis}(u,v)\)。于是可以以 \(\mathcal O(n)\) 的询问次数完成。

但实际上这个问题还是和 \(\text{oi-wiki}\) 上的主元素问题有些许不同:我们并没有保证 一定存在主元素。所以对于最终 \(\text{count}>0\) 还需要再次判断选出元素的出现次数和减去其它元素的出现次数,这也是 \(\mathcal O(n)\) 的。

但是询问次数变成了 \(\mathcal O(4n)\),所以考虑优化(代码实现请见 \(\rm this\)):当 !w[i]continue;,考虑两次栈空之间发生了啥,实际上就是增长-下降-增长-下降……的过程,显然增长数等于下降数,而增长数近似于 continue; 语句优化的询问,所以可以认为优化了 \(\mathcal O(0.5n)\) 次。这道题就做完了。

arc119F - AtCoder Express 3

题意简述:一条铁路共 \(N+1\) 个站点,从左到右以 \(0\)\(N\) 标号,对每一个 \(i\; (0\leqslant i\leqslant N-1)\)\(i\) 号车站与 \(i+1\) 号车站有一条 双向 铁路。

每个站点可能属于 A 类或 B 类,最近 的同类车站间也会有一条双向铁路。\(0\) 号和 \(N\) 号站点可以看做既属于 A 类又属于 B 类。

现给出已经确定的每一个车站的类型,对剩下所有未确定的车站进行分类,求有多少种分类方式使得从 \(0\)\(N\) 可以只经过不超过 \(K\) 条铁路,对 \(10^9+7\) 取模。

\(N\leqslant 4000\).

一些闲话:这题的战线真的拖了极长,我 \(\mathtt{dp}\) 好烂啊。但是这种 \(\tt dp\) 怎么能想得到啊!

题目的一大难点在于最近的同类车站之间的连边,考虑这类连边有什么作用:加速从 A 跳到 A 的时间;从 A 跳到最近的一个 A,返回来跳到 B,这可能导致 B 的最短路减小。

但是用 \(\mathtt{dp}\) 非常难维护 "先跳到后面,再跳回来" 的情况,从一个简单的情况开始考虑:不同类车站就在自己的下一个位置。设当前处理到位置为 \(i\)(不妨设它是 A 类站点,那么下一个车站为 B 类),在 \([1,i]\) 中离 \(i\) 最近的 A 类站点(也就是 \(i\))的最短路为 \(j\),离 \(i\) 最近的 B 类站点的最短路为 \(k\),如何将这个状态转移到 \(i+1\)

由于同时我们也假设了 \(i+1\) 号站点的后一个站点为 A,于是 \(j'\leftarrow j,k'\leftarrow \min\{k+1,j+2\}\).

事实上用这个方法 \(\tt dp\) 就已经足够了,先记 \(dp(i,j,k,0/1)\) 为当前处理到位置为 \(i\),在 \([1,i]\) 中离 \(i\) 最近的 A 类站点的最短路为 \(j\),离 \(i\) 最近的 B 类站点的最短路为 \(k\)\(i\) 号站点为 A/B.

首先考虑处理到位置 \(N-1\),由于 \(N\) 位置既可以作为 A 也可以作为 B,所以直接作为答案是没有问题的。

之前已经讨论了相邻互异的情况,现在讨论 \(i,i+1\) 站点类型相同的情况(不妨令它们均为 A 类车站)。可以发现从离 \(i\) 最近的 B 转移过来是不影响的,如果从上一个 A 转移过来则需要讨论:

  • 如果上一个 A 未通过假设的 B 进行转移,那么贡献还是 \(j+1\)

  • 如果上一个 A 通过假设的 B 进行转移,此时的 \(j+1\) 就相当于 \((k+2)+1\),肯定不如从最近的 B 转移过来优。

于是可以在 \(\mathcal{O}(N^3)\) 内解决这个问题。

考虑优化,可以发现 \(|j-k|\leqslant 2\),于是时间复杂度降到 \(\mathcal{O}(N^2)\).

posted on 2022-07-12 16:47  Oxide  阅读(142)  评论(0编辑  收藏  举报