差分

原理:
参考网页
维护一个差分序列, 这样可以快速对一个区间[l, r]整体加上或减去一个整数
如何维护?
初始的数组a[n], 建立一个差分数组s[n], 使其s[i] = a[i] - a[i - 1]
对区间[l, r]加上一个整数x, 对差分数组s[l], s[r + 1]加上一个整数x,就相当于在原数组[l, r]加上了这个整数x.
举例
目前 a={ 1,2,3,3,3,3},则对应的差分数列 p={ 1,1,1,0,0,0}。
给 [3, 5] 加上首项为2、公差为 1 的等差数列,及{ 2,3,4}。那么原数列变为 a={ 1,2,5,6,7,3},对差分数列变为 p={ 1,1,3,1,1,-4}。

从差分数组反推原数组
a[1] = p[0] + p[1] = 1
a[2] = p[0] + p[1] + p[2] = 2
a[3] = p[0] + p[1] + p[2] + p[3] = 5

以此类推, 只要像前缀和一样快速维护一个差分数组的前n项和, 就可以快速实现对区间加上或者减去一个整数
说明 a 区间加等差,相当于 p 区间加常数、端点单点修改。也就是区间加自然是给 p_{[l+1, r]} 加上 d。

最后像前缀和一样用差分数组还原出修改后的数组

#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 1e6 + 10;
int a[N], _a[N], s[N];
int main()
{
    ios::sync_with_stdio(0);
    int n, k;
    cin >> n >> k;
    for (int i = 0; i < k; i++)
    {
        int l, r;
        cin >> l >> r;
        a[l] += 1;
        a[r + 1] -= 1;
    }
    for (int i = 1; i <= n;  i++)
    {
        s[i] = s[i - 1] + a[i];
    }
    sort(s + 1, s + n + 1);
    cout << s[n + 1 >> 1] << endl;
    return 0;
}
posted @ 2021-08-09 14:50  梨花满地  阅读(101)  评论(0)    收藏  举报