【基础算法】差分

一维差分

差分可以看成前缀和的逆运算
构造差分数组b[]的方法:
image

作用:可以在\(O(1)\)的时间给区间[l, r]内的数都加上一个数c
模板题:AcWing 797. 差分

#include <iostream>

using namespace std;

const int N = 1e5 + 10;

int n, m;
int a[N], b[N];

void insert(int l, int r, int c)
{
    b[l] += c;
    b[r + 1] -= c;
}

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++ ) 
    {
        scanf("%d", &a[i]);
        insert(i, i, a[i]);
    }
    
    while(m -- )
    {
        int l, r, c;
        scanf("%d%d%d", &l, &r, &c);
        insert(l, r, c);
    }
    
    for(int i = 1; i <= n; i ++ )
    {
        a[i] = a[i - 1] + b[i];
        printf("%d ", a[i]);
    }
    return 0;
}

二维差分

image
模板题:AcWing 798. 差分矩阵

#include <iostream>

using namespace std;

const int N = 1010;

int n, m, q;
int a[N][N], b[N][N];

void insert(int x1, int y1, int x2, int y2, int c)
{
    b[x1][y1] += c;
    b[x1][y2 + 1] -= c;
    b[x2 + 1][y1] -= c;
    b[x2 + 1][y2 + 1] += c;
}

int main()
{
    scanf("%d%d%d", &n, &m, &q);
    
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= m; j ++ )
        {
            scanf("%d", &a[i][j]);
            insert(i, j, i, j, a[i][j]);
        }
        
    while(q -- )
    {
        int x1, y1, x2, y2, c;
        scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &c);
        insert(x1, y1, x2, y2, c);
    }
        
    for(int i = 1; i <= n; i ++ )
    {    
        for(int j = 1; j <= m; j ++ )
        {
            a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + b[i][j];
            printf("%d ", a[i][j]);
        }
        puts("");
    }
    return 0;
}
posted @ 2021-09-12 17:21  Tshaxz  阅读(217)  评论(0编辑  收藏  举报
Language: HTML