题意
给定一个整数序列 $a[1],a[2],….a[n]$,那么对于 $a$ 序列的任意一个连续子序列 $a[L],a[L+1],……a[R]$,其中 $1<=L<=R<=n$, 求出该连续子序列的中位数,记为 $b[L][R]$。
显然 $b$ 数组共有 $n*(n+1)/2$ 个整数。
输出 $b$ 数组的中位数。
分析
关于中位数有一个 Trick:
- 我们二分一个数 $mid$,对于原序列中 $\ge mid$ 的数,我们标记为 $1$;反之,对于 $< mid$ 的数,我们标记为 $−1$。
- 标记结束后,如果一个区间内的标记和大于等于 $0$,说明中位数大于等于 $mid$,那么向右二分;反之向左。
对于本题,我们对 $b$ 数组二分它的中位数 $mid$,并按 $mid$ 对 $a$ 数组进行 $+1,-1$ 标记。然后问题就变为了:统计有多少个区间的标记和 $\ge 0$。
记这个区间数为 $cnt$,若 $cnt\ge \lfloor \frac{n(n+1)/2+1}{2} \rfloor$,说明 $b$ 数组实际中位数 $\ge mid$,向右二分。否则向左二分。
怎么求有多少个区间的标记和 $\ge 0$ 呢?我们可以做一个前缀和 $s$,统计 $i < j$ 且 $s[i] \le s[j]$ 的个数。这是一个二维偏序问题,可以搭配树状数组解决。
$O(nlog^2n)$。
| |
- https://img.atcoder.jp/arc101/editorial.pdf
- https://www.luogu.com.cn/blog/DZN2004/atcoder-shang-di-yi-suo-ti
- https://zuytong.blog.luogu.org/post-20221012-d#
@ 2022/10/15 SM 模拟赛。