uoj177 - 新年的腮雷
题意简述:给定 nn 个正整数 a1,…,ana1,…,an 和 mm 个正整数 b1,…,bmb1,…,bm,进行 n−1m−1n−1m−1 次操作,每次选择 aa 中的 mm 个正整数 x1,…,xmx1,…,xm,删去它们,加入 max{xi+bi}max{xi+bi},求最后得到的数的最小值。
n,m⩽5⋅104n,m⩽5⋅104,(m−1)∣(n−1)(m−1)∣(n−1),ai⩽108ai⩽108,bi⩽107bi⩽107.
不妨二分答案并倒着做,则问题转化为:考虑一个初始只有一个元素 midmid 的集合 TT,每次操作选择一个元素 xx 拆成 mm 个 x−bix−bi,问最后能不能将集合中元素进行某种排列后有 ∀i∈[1,n],xi⩾ai∀i∈[1,n],xi⩾ai.
将 {a},{b}{a},{b} 从小到大排序,我们考虑拆解集合 TT 元素的同时从后往前与 {a}{a} 进行匹配:
- 若 maxT<maxamaxT<maxa,无解;
- 若 maxa⩽maxT<b1+maxamaxa⩽maxT<b1+maxa,此时即使将 TT 中最大元素拆掉也不能与 maxamaxa 匹配,所以只能用当前集合 TT 中的元素,显然取大于等于 maxamaxa 且最小的元素;
- 若 maxT⩾b1+maxamaxT⩾b1+maxa,则将 TT 的最大元素拆掉不劣。
时间复杂度 O(nlognlogV)O(nlognlogV).
[IOI2015] Towns
题意简述:这是一道交互题。有一个 "圆方树",所有叶子都是圆点,所有非叶子都是方点,且方点度数至少为 33。一共有 nn 个圆点,方点数量未知。边带权。你可以询问两个圆点的距离。你需要确定:
树的半径的长度。定义 r(C)r(C) 表示离点 CC 距离最远的圆点的距离,那么半径定义为 r(C)r(C) 的最小值;
是否存在一个 r(C)r(C) 最小的 CC 使得 CC 是带权重心。带权重心的每个子树都有不超过 ⌊n/2⌋⌊n/2⌋ 个圆点。
你可以询问 ⌈7n/2⌉⌈7n/2⌉ 次。6⩽n⩽1106⩽n⩽110.
"离点 CC 距离最远" 提示我们寻找直径,因为树上一个点的最远点一定是直径的某个端点。采用两遍搜索寻找直径的方法(不妨设最初随机的点为 cc,cc 找到的直径端点为 aa,另一个直径端点为 bb),可以用 2n−22n−2 次询问找到直径,a,ca,c 与所有点的距离。
由于 r(C)r(C) 一定是 CC 和直径端点距离的最大值,所以我们实际上只需要确定 CC 与直径的距离 dd,CC 走到直径的第一个点 C′C′ 在直径上的位置(不妨设 C′C′ 到 aa 的距离为 ss,到 bb 的距离为 tt),那么可以列出方程
由此可以解出 d,s,t,我们也就找到了半径。
容易发现,r(C) 最小的点一定是直径中点,而直径中点个数至多为 2,我们依次判断中点是否能成为带权重心……吗?实际上,这两个点 只可能有一个点是带权重心!不妨设这两个点为 u,v,u 是离 a 更近的点。将所有 s⩽su 的点个数记为 cnt,容易发现 t⩽tv 的点个数为 n−cnt。当 cnt<n−cnt 时,u 的 v 侧子树已经大于 ⌊n/2⌋,反之同理。
一个很妙的转化是,考虑以 u 为根,如果存在超过 ⌊n/2⌋ 个点在 u 的同一个子树中,u 就不是带权重心。"⌊n/2⌋","同一个子树"……这实际上可以转化成主元素问题!这个问题有一个经典的空间 O(1),时间 O(n) 的做法,可以去 oi-wiki 上看。如何判断两个点是否在同一子树呢?由于直径中点在直径上(这不是废话吗?),所以可以利用每个点之前求的 s,t,d 来算出每个点到直径中点的距离 D:若 u,v 在同一子树,那么有 D(u)+D(v)>dis(u,v)。于是可以以 O(n) 的询问次数完成。
但实际上这个问题还是和 oi-wiki 上的主元素问题有些许不同:我们并没有保证 一定存在主元素。所以对于最终 count>0 还需要再次判断选出元素的出现次数和减去其它元素的出现次数,这也是 O(n) 的。
但是询问次数变成了 O(4n),所以考虑优化(代码实现请见 this):当 !w[i]
时 continue;
,考虑两次栈空之间发生了啥,实际上就是增长-下降-增长-下降……的过程,显然增长数等于下降数,而增长数近似于 continue;
语句优化的询问,所以可以认为优化了 O(0.5n) 次。这道题就做完了。
arc119F - AtCoder Express 3
题意简述:一条铁路共 N+1 个站点,从左到右以 0 到 N 标号,对每一个 i(0⩽i⩽N−1),i 号车站与 i+1 号车站有一条 双向 铁路。
每个站点可能属于 A 类或 B 类,最近 的同类车站间也会有一条双向铁路。0 号和 N 号站点可以看做既属于 A 类又属于 B 类。
现给出已经确定的每一个车站的类型,对剩下所有未确定的车站进行分类,求有多少种分类方式使得从 0 到 N 可以只经过不超过 K 条铁路,对 109+7 取模。
N⩽4000.
一些闲话:这题的战线真的拖了极长,我 dp 好烂啊。但是这种 dp 怎么能想得到啊!
题目的一大难点在于最近的同类车站之间的连边,考虑这类连边有什么作用:加速从 A 跳到 A 的时间;从 A 跳到最近的一个 A,返回来跳到 B,这可能导致 B 的最短路减小。
但是用 dp 非常难维护 "先跳到后面,再跳回来" 的情况,从一个简单的情况开始考虑:不同类车站就在自己的下一个位置。设当前处理到位置为 i(不妨设它是 A 类站点,那么下一个车站为 B 类),在 [1,i] 中离 i 最近的 A 类站点(也就是 i)的最短路为 j,离 i 最近的 B 类站点的最短路为 k,如何将这个状态转移到 i+1?
由于同时我们也假设了 i+1 号站点的后一个站点为 A,于是 j′←j,k′←min{k+1,j+2}.
事实上用这个方法 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 转移过来优。
于是可以在 O(N3) 内解决这个问题。
考虑优化,可以发现 |j−k|⩽2,于是时间复杂度降到 O(N2).
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
· 程序员转型AI:行业分析
2021-07-12 Codeforces Global Round 12