Acwing 题解 [acwing-2041-干草堆] (Cpp)
作者:互联网
题目描述
贝茜对她最近在农场周围造成的一切恶作剧感到抱歉,她同意帮助农夫约翰把一批新到的干草捆堆起来。
开始时,共有 N 个空干草堆,编号 1∼N。
约翰给贝茜下达了 K 个指令,每条指令的格式为 A B
,这意味着贝茜要在 A..B范围内的每个干草堆的顶部添加一个新的干草捆。
例如,如果贝茜收到指令 10 13
,则她应在干草堆 10,11,12,1310,11,12,13 中各添加一个干草捆。
在贝茜完成了所有指令后,约翰想知道 N 个干草堆的中值高度——也就是说,如果干草堆按照高度从小到大排列,位于中间的干草堆的高度。
方便起见,N 一定是奇数,所以中间堆是唯一的。
请帮助贝茜确定约翰问题的答案。
输入格式
第一行包含 N 和 K。
接下来 K 行,每行包含两个整数 A,B用来描述一个指令。
输出格式
输出完成所有指令后,NN 个干草堆的中值高度。
数据范围
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。
思路
一开始我们大家可能都能想到使用一个数组来存对应干草堆的高度,然后根据输入的值每次都依次遍历一遍更新数组内的元素,最后从小到大排个序,然后再取数组中间的值输出。时间复杂度为O(\(n^2\))
但是随着数据量的增大,我们所花费的时间会大大的增加,那么有没有什么更好的办法呢?我们能不能只记录两个端点的值呢?
这个时候我们就需要用到差分数组的思想了
差分数组
首先我们先来解释一下什么是差分,差分就是原始数组中相邻两个元素之间的差值
原始数组 a[x] [0,2,5,4,9,7,10,0]
差分数组 d[x] [*,2,3,-1,5,-2,3,-10]
求差分数组的公式
d[i]=a[i+1]-a[i]
差分数组有什么用
当我们需要给一个区间内的元素同时增加某一个数的时候,我们可以使用差分数组的方式来操作,这样可以大大的减少我们操作的次数
例子:
将区间[2,6]的值全部加上1
原始数组 a[x] [0,2,5+1,4+1,9+1,7+1,10+1,0]
差分数组 d[x] [*,2,3+1,-1,5,-2,3,-10-1]
从上述的例子中我们不难发现,我们对原始数组操作了5次,而对差分数组仅仅只操作了两次,当数据量越大的时候,它们性能上的差距会更大。
差分数组怎么用
当我们对某个区间进行增减某个值的时候,它的差分数组对应的区间左端点的值会同步变化,而它的右端点的后一个值则会相反地变化
代码实现
#include <bits/stdc++.h>
using namespace std;
int ls[1000001];
int main(){
int N,K;
cin >> N >> K;
int m,n;
for(int i=0;i<K;i++){
cin >> m >> n;
ls[m]++;
ls[n+1]--;
}
for(int i=2;i<N+1;i++){
ls[i] = ls[i]+ls[i-1];
}
sort(ls+1,ls+N);
cout << ls[N/2] << endl;
return 0;
}
时间复杂度: O(N)
空间复杂度: O(N)
标签:10,2041,int,题解,差分,数组,贝茜,干草堆 来源: https://www.cnblogs.com/egospace/p/15760290.html