其他分享
首页 > 其他分享> > Acwing 题解 [acwing-2041-干草堆] (Cpp)

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