「CF2077D」Maximum Polygon

Description

Link:CF2077D

给出一个长度为 nn 的数组 aa,你需要找出字典序最大的子序列 ss,使得 ss 可以作为多边形的边长。

当且仅当 s3|s| \geq 3 且满足以下条件时,ss 可以作为多边形的边长

2max(s1,,ss)<s1++ss2 \cdot \max(s_1, \cdots, s_{|s|}) < s_1 + \cdots + s_{|s|}

数据范围:3n2×1053 \leq n \leq 2 \times 10^51ai1091 \leq a_i \leq 10^9

时空限制:33s / 250250MiB。

Solution

考虑当子序列最大值 mx\mathrm{mx} 已经确定时,要如何求出字典序最大的子序列 ss?此时相当于要选出总和 >2mx> 2\cdot \mathrm{mx} 的字典序最大的子序列。

考虑以下贪心过程:从左往右扫描每一个 aia_i,设 sum\mathrm{sum} 表示当前 ss 元素之和。

  • 取出当前 ss 的最后一个元素 xx,若 ai>xa_i > xsumx+j=inaj>2mx\mathrm{sum} - x + \sum_{j = i}^n a_j > 2 \cdot \mathrm{mx},则可以将 xx 替换成 aia_i。重复该过程直到无法替换或 ss 为空。
  • aia_i 放入当前 ss 的末尾。

可以证明,子序列 ss 的最大值一定是 {ai}\{a_i\} 的前 log2A\log_2 A 大其中之一。

考虑一个序列 vv,其中 vv任何子序列都不可以作为多边形的边长。则升序排序过后一定满足 vij=1i1vjv_i \geq \sum_{j = 1}^{i - 1}v_j,为了最大化 vv 的长度,有 v1=1v_1 = 1vi=2i2v_i = 2^{i - 2}i2i \geq 2)。

故满足任何子序列都不可以作为多边形边长的序列 vv,长度不超过 log2A\log_2 A

换言之,长度超过 log2A\log_2 A 的序列 vv,必定有一个子序列可以作为多边形的边长

假设答案的子序列 ss 的最大值不是 {ai}\{a_i\} 的前 log2A\log_2 A 大其中之一,则将前 log2A\log_2 A 大构成的子序列 tt 取出,由上述推导,tt 必定有一个子序列 tt' 可以作为多边形的边长。将 tt' 插入子序列 ss 中,显然满足条件的同时字典序更大。

时间复杂度 O(nlogA)\mathcal{O}(n \log A)