1. 问题描述:
贝茜对她最近在农场周围造成的一切恶作剧感到抱歉,她同意帮助农夫约翰把一批新到的干草捆堆起来。开始时,共有 N 个空干草堆,编号 1∼N。约翰给贝茜下达了 K 个指令,每条指令的格式为 A B,这意味着贝茜要在 A..B 范围内的每个干草堆的顶部添加一个新的干草捆。例如,如果贝茜收到指令 10 13,则她应在干草堆 10,11,12,13 中各添加一个干草捆。在贝茜完成了所有指令后,约翰想知道 N 个干草堆的中值高度——也就是说,如果干草堆按照高度从小到大排列,位于中间的干草堆的高度。方便起见,N 一定是奇数,所以中间堆是唯一的。请帮助贝茜确定约翰问题的答案。
输入格式
第一行包含 N 和 K。接下来 K 行,每行包含两个整数 A,B,用来描述一个指令。
输出格式
输出完成所有指令后,N 个干草堆的中值高度。
数据范围
1 ≤ N ≤ 10 ^ 6,
1 ≤ K ≤ 25000,
1 ≤ A ≤ B ≤ N
输入样例:
7 4
5 5
2 4
4 6
3 5
输出样例:
1
样例解释
贝茜完成所有指令后,各堆高度为 0,1,2,3,3,1,0。将各高度从小到大排序后,得到 0,0,1,1,2,3,3,位于中间的是 1。
来源:https://www.acwing.com/problem/content/2043/
2. 思路分析:
我们可以先将模型抽象一下,可以发现每一次都是对整个区间加上1,属于经典的差分操作,差分操作中将整个区间加上一个数字,这里是给整个区间加上1。差分中整个区间加上某个数字等价于区间左端点的位置加上一个数字,右端点 + 1的位置减去一个数字,如果要求操作之后的数组那么直接求解差分数组的前缀和即可,所以对于这道题目来说我们可以先求解出差分数组再求解出前缀和数组对于前缀和数组排序之后求解中位数即可。
3. 代码如下:
class Solution:
def process(self):
n, m = map(int, input().split())
a = [0] * (n + 2)
for i in range(m):
l, r = map(int, input().split())
a[l] += 1
a[r + 1] -= 1
for i in range(1, n + 1):
a[i] += a[i - 1]
# 弹出第一个元素0
a.pop(0)
# 弹出最后一个元素
a.pop()
a.sort()
return a[n // 2]
if __name__ == "__main__":
print(Solution().process())