前缀与差分

1.一维前缀和

    for(int i = 1; i <= n; i++){
        scanf("%d", a + i);
        s[i] = s[i - 1] + a[i];
    }
    //求x到y这个区间的和
    while(m--){
        int x, y;
        cin >> x >> y;
        printf("%d\n", s[y] - s[x - 1]);
    }

2.二维前缀和

    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            scanf("%d", &a[i][j]);
            s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + a[i][j];
        }
    }
    //求(x2, y2)到(x1, y1)的区间和
    while(q--){
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        printf("%d\n", s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);
    }

3.一维差分

    for(int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
        d[i] = a[i] - a[i - 1];
    }
    while(m--){
    //将x, y这个区间的数加上z。
        int x, y, z;
        cin >> x >> y >> z;
        d[x] += z;
        d[y + 1] -= z;
    }
    for(int i = 1; i <= n; i++){
        d[i] += d[i - 1];
        cout << d[i] << " ";
    }

4.二维差分 构造差分矩阵

void insert(int x1, int y1, int x2, int y2, int c){
    d[x1][y1] += c;
    d[x2 + 1][y1] -= c;
    d[x1][y2 + 1] -= c;
    d[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, z;
        cin >> x1 >> y1 >> x2 >> y2 >> z;
        insert(x1, y1, x2, y2, z);
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            d[i][j] += d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1];
            cout << d[i][j] << " ";
        }cout << endl;
    }
    return 0;
}
发布了103 篇原创文章 · 获赞 203 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_45432665/article/details/104340684