前缀和与差分

发布时间 2023-08-27 23:38:50作者: -37-

前缀和

一维前缀和

公式:

\[s[i] = s[i - 1] + a[i] \]

模板:

const int N = 10000 + 10;

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

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

二维前缀和

公式:

\[求前缀和:s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j]\\ 算子子矩阵和:s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1] \]

模板:

const int N = 10000 + 10;

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

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]);
            s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
        }
    }
    
    while (q--) {
        int x1,y1,x2,y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        printf("%d\n",s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);
    }
    return 0;
}

差分

一维差分

公式:

\[b[l]\ +=\ c\quad b[r + 1]\ -=\ c \]

模板:

const int N = 10000 + 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++) {
        b[i] += b[i - 1];
        printf("%d ",b[i]);
    }
    return 0;
}

二维差分

公式:

\[b[x1][y1]\ +=\ c\quad b[x1][y2 + 1]\ -=\ c\\ b[x2 + 1][y1]\ -=\ c\quad b[x2 + 1][y2 + 1]\ +=\ c \]

模板:

const int N = 10000 + 10;

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;
        cin >> 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++) {
			b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];
            printf("%d ",b[i][j]);
        }
        puts("");
    }
    return 0;
}