#P17143. [NOI 2026] 中位数

[NOI 2026] 中位数

背景

题面、样例附件来自 QOJ。

提交到洛谷上时,无需引用头文件 #include "median.h"。直接将

void init(int c, int t);
int median(int n, int k, std::vector<int> a);

复制到程序开头,同时选用 C++17 或者更高版本编译器编译。

题目描述

对于大小为 mm 的可重集 S={x0,x1,…,xm−1}S=\{x_0,x_1,\ldots,x_{m-1}\},设其所有元素 从大到小 排序后的结果为 y0≥y1≥⋯≥ym−1y_0\ge y_1\ge\cdots\ge y_{m-1}。定义其 中位数 Median⁡(S)\operatorname{Median}(S) 为其中第 ⌈m2⌉\left\lceil\frac{m}{2}\right\rceil 大的数,即 $\operatorname{Median}(S)=y_{\left\lceil\frac{m}{2}\right\rceil-1}$。注意:本题中的中位数定义与常规定义可能有所不同。

给定长度为 nn 的序列 [a0,a1,…,an−1][a_0,a_1,\ldots,a_{n-1}],以及一个正整数 kk(k≤nk\le n)。定义一个 划分 如下:选择一个长度为 k−1k-1 的递增下标序列 0<b1<⋯<bk−1<n0<b_1<\cdots<b_{k-1}<n,即可将原序列划分为 kk 个段,对应的下标区间依次为 [0,b1),[b1,b2),…,[bk−1,n)[0,b_1),[b_1,b_2),\ldots,[b_{k-1},n)。

对于一个划分,定义该划分的 平衡度 如下:对于划分出的每个段,计算其中所有元素形成的可重集的中位数,则这 kk 个中位数形成的可重集的中位数即为该划分的 平衡度。形式化地,对于划分 b1,…,bk−1b_1,\ldots,b_{k-1},记 b0=0b_0=0,bk=nb_k=n,设第 ii(0≤i<k0\le i<k)个段中所有元素形成的可重集的中位数为 $c_i=\operatorname{Median}(\{a_{b_i},a_{b_i+1},\ldots,a_{b_{i+1}-1}\})$,则该划分的平衡度为 Median⁡({c0,…,ck−1})\operatorname{Median}(\{c_0,\ldots,c_{k-1}\})。

请求出所有划分中平衡度的最大值。

【实现细节】

选手不需要,也不应该实现 main 函数。

选手需要确保提交的程序源文件包含头文件 median.h,即在程序开头加入以下代码:

#include "median.h"

选手需要在提交的程序源文件 median.cpp 中实现以下两个函数:

void init(int c, int t);
  • c,tc,t 分别表示测试点编号与测试数据组数。c=0c=0 表示该测试点为样例。
  • 对于每个测试点,该函数会在程序开始运行时被评测程序调用恰好一次。
int median(int n, int k, std::vector<int> a);
  • n,k,an,k,a 分别表示序列长度、划分的段数与给定的序列。
  • 该函数需要返回平衡度的最大值。
  • 对于每个测试点,该函数会被评测程序调用恰好 tt 次。

本试题目录下的 template_median.cpp 是提供的示例代码,选手可参考并实现自己的代码。

输入格式

【测试程序方式】

选手可以在本题目录下使用如下命令编译得到可执行文件:

g++ grader.cpp median.cpp -o median -O2 -std=c++14 -static

对于编译得到的可执行文件 median:

  • 可执行文件将从标准输入读入以下格式的数据:
    • 第一行包含两个非负整数 c,tc,t。
    • 接下来依次为每组测试数据。对于每组测试数据:
      • 第一行包含两个正整数 n,kn,k。
      • 第二行包含 nn 个正整数 a0,a1,…,an−1a_0,a_1,\ldots,a_{n-1}。
  • 可执行文件将输出以下格式的数据至标准输出:
    • 对于每组测试数据,输出一行一个正整数,表示平衡度的最大值。
0 2
10 4
6 5 1 9 2 3 10 7 4 8
10 5
5 7 3 10 8 2 9 1 6 4
9
8

提示

【样例 11 解释】

对于第一组测试数据,一种平衡度最大的划分为 b1=3b_1=3,b2=5b_2=5,b3=7b_3=7,其将原序列划分为 44 个段 [6,5,1][6,5,1]、[9,2][9,2]、[3,10][3,10]、[7,4,8][7,4,8],段中所有元素的中位数分别为 5,9,10,75,9,10,7,因此该划分的平衡度为 Median⁡({5,9,10,7})=9\operatorname{Median}(\{5,9,10,7\})=9。

对于第二组测试数据,一种平衡度最大的划分为 b1=2b_1=2,b2=4b_2=4,b3=6b_3=6,b4=8b_4=8,其将原序列划分为 55 个段 [5,7][5,7]、[3,10][3,10]、[8,2][8,2]、[9,1][9,1]、[6,4][6,4],段中所有元素的中位数分别为 7,10,8,9,67,10,8,9,6,因此该划分的平衡度为 Median⁡({7,10,8,9,6})=8\operatorname{Median}(\{7,10,8,9,6\})=8。

【样例 22】

见选手目录下的 median/median2.in 与 median/median2.ans。

该样例满足测试点 66 的约束条件。

【样例 33】

见选手目录下的 median/median3.in 与 median/median3.ans。

该样例满足测试点 99 的约束条件。

【样例 44】

见选手目录下的 median/median4.in 与 median/median4.ans。

该样例满足测试点 1414 的约束条件。

【样例 55】

见选手目录下的 median/median5.in 与 median/median5.ans。

该样例满足测试点 18∼2018\sim20 的约束条件。

【数据范围】

设 NN 为单个测试点内所有测试数据的 nn 的和。对于所有测试数据,均有:

  • 1≤t≤201\le t\le20;
  • 5≤n≤1065\le n\le10^6,2≤k≤n2\le k\le n,N≤106N\le10^6;
  • 对于所有 0≤i<n0\le i<n,均有 1≤ai≤n1\le a_i\le n。

::cute-table{tuack} | 测试点编号 | N≤N\le | n≤n\le | kk | 特殊性质 | |:-:|:-:|:-:|:-:|:-:| | 1,21,2 | 4040 | 2020 | ≤n\le n | 无 | | 3∼53\sim5 | 800800 | 8080 | ^ | AA | | 66 | ^ | ^ | ^ | 无 | | 7,87,8 | 80008000 | 800800 | ^ | AA | | 99 | ^ | ^ | ^ | 无 | | 1010 | 2×1052\times10^5 | 2×1052\times10^5 | =2=2 | ^ | | 1111 | ^ | ^ | =3=3 | ^ | | 12,1312,13 | ^ | ^ | =5=5 | ^ | | 1414 | ^ | ^ | ≤10\le10 | ^ | | 1515 | ^ | ^ | ≡0(mod2)\equiv0\pmod 2 | ^ | | 16,1716,17 | 10610^6 | 10610^6 | >5>5 | ^ | | 18∼2018\sim20 | ^ | ^ | ≤n\le n | ^ |

特殊性质 AA:对于所有 0≤i<n0\le i<n,均有 ai≤2a_i\le2。