【算法】——前缀和与差分

159 阅读1分钟

前缀和与差分

模版

前缀和

  1. 一维前缀和
//一维前缀和
int s[100];
int n;
for (int i = 1; i <= n; i++) {
    int tmp;
    scanf("%d", &tmp);
    s[i] = s[i - 1] + tmp;  //s[i] += s[i - 1]
}
int q = s[l] - s[r - 1];
  1. 二维前缀和
//二维前缀和
int s[100][100];
int n, m;
for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
        int tmp;
        scanf("%d", &tmp);
        s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + tmp;
        //s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1]
    }
}

int q = s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1];

差分

  1. 一维差分
//一维差分
int s[100];
void insert(int l, int r, int x)
{
    s[l] += x;
    s[r + 1] -= x;
}
//求原序列就是求一维前缀和
s[i] += s[i - 1]
  1. 二维差分
//二维差分
int s[100][100];
void insert(int x1, int y1, int x2, int y2, int x)
{
    s[x1][y1] += x;
    s[x2 + 1][y1] -= x;
    s[x1][y2 - 1] -= x;
    s[x2 - 1][y2 - 1] += x;
}
//求原序列就是求二维前缀和
s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1]
}