差分

1. 差分的原理

差分数组: diff[i] = a[i] - a[i - 1]

对差分数组做前缀和可以还原为原数组:

diff[1] = a[1]

diff[2] = a[2] - a[1]

diff[3] = a[3] - a[2]

......

diff[n] = a[n] - a[n - 1]

易得:

diff[1] + diff[2] + diff[3] + ... + diff[i]

= a[i]

据此,差分数组可以实现快速的区间修改

Eg: 将区间[l, r]都加上 x :

diff[l] += x;

diff[r + 1] -= x

然后做前缀和运算

2. 差分的实现

for(itn i = 1; i <= n i ++ )
    diff[i] = a[i] - a[i - 1];

diff[l] += x;
diff[r + 1] -= x;

a[i] = a[i - 1] + diff[i];

3. 例题

区间更新

#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N], diff[N];

void solve(int n, int m)
{
    for(int i = 1; i <= n; i ++ ) cin >> a[i];
    for(int i = 1; i <= n; i ++ ) diff[i] = a[i] - a[i - 1];

    while(m -- )
    {
        int x, y, z;
        cin >> x >> y >> z;
        
        diff[x] += z;
        diff[y + 1] -= z;
    }
    for(int i = 1; i <= n; i ++ ) a[i] = a[i - 1] + diff[i];
    

    for(int i = 1; i <= n; i ++ ) cout << a[i] << ' ';
    cout << endl;
}

int main()
{
    int n, m;
    // 当不知道有几个样例时,这么干:
    while(cin >> n >> m) solve(n, m);

    return 0;
}

此外,当不知道有几组样例时,可以使用while(cin >> n >> m) solve(n, m); 使用 solve 函数封装很方便


南池北塘
1 声望0 粉丝

« 上一篇
【STL】map