计蒜客 - 矩阵查询

计蒜客 矩阵查询

题目描述

给出 N × N N \times N N×N 的矩阵 A A A,初始时均为 0 0 0

我们需要支持两种操作:

$ C \ x_1 \ y_1 \ c $,表示 ( x 1 , y 1 ) (x_1, y_1) (x1,y1) 上的元素加上 c c c

( 1 ≤ x 1 , y 1 ≤ N , 1 ≤ c ≤ 100 ) (1 \leq x_1, y_1 \leq N, 1 \leq c \leq 100) (1x1,y1N,1c100)

Q   x 1   y 1   x 2   y 2 Q \ x_1 \ y_1 \ x 2 \ y_2 Q x1 y1 x2 y2,查询子矩阵元素之和。

( 1 ≤ x 1 ≤ x 2 ≤ N , 1 ≤ y 1 ≤ y 2 ≤ N ) (1 \leq x_1 \leq x_2 \leq N, 1 \leq y_1 \leq y_2 \leq N) (1x1x2N,1y1y2N)

样例

样例输入

第一行两个整数 N , Q ( 1 ≤ N ≤ 1000 , 1 ≤ Q ≤ 50000 ) N,Q(1\leq N\leq 1000, 1\leq Q\leq 50000) N,Q(1N1000,1Q50000)。接下来 Q Q Q 行,每行一个操作。

3 5
C 1 1 3
Q 1 1 2 3
C 1 2 1
C 2 1 1
Q 1 1 2 3

样例输出

对于每个询问操作,一行一个整数,表示矩阵的和。

3
5

算法与数据结构

树状数组

题解

裸的树状数组。子矩阵的和只需要使用四个矩阵的容斥就可以完成。

完整代码

#include <bits/stdc++.h>

using namespace std;

int n = 0;
const int MAX_N = 1007;
int C[MAX_N][MAX_N] = {{0}}; // 树状数组 C

int lowBit(int x) {
    return x & -x; // return x & (x ^ (x - 1))
}

// 查询
int sum(int i, int j){
    int res = 0;
    for(int x = i; x; x -= lowBit(x))
        for(int y = j; y; y -= lowBit(y))
            res += C[x][y];
    return res;
}

// 修改
void change(int i, int j, int delta){
    for(int x = i; x < MAX_N; x += lowBit(x)) {
        for (int y = j; y < MAX_N; y += lowBit(y)) {
            C[x][y] += delta;
        }
    }
}

// 子矩阵的操作只需要使用 4 个树状数组矩阵的容斥就可以解决

// 子矩阵查询
int subSum(int x1, int y1, int x2, int y2) {
    return sum(x2, y2) - sum(x1 - 1, y2) - sum(x2, y1 - 1) + sum(x1 - 1, y1 - 1);
}

int main() {
    int t;
    scanf("%d%d", &n, &t);
    for (int i = 0; i < t; i++) {
        char op;
        scanf("\n%c", &op);
        if (op == 'C') {
            int x, y, c;
            scanf("%d%d%d", &x, &y, &c);
            change(x, y, c);
        } else {
            int x1, y1, x2, y2;
            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
            printf("%d\n", subSum(x1, y1, x2, y2));
        }
    }

    return 0;
}

欢迎关注我的个人博客以阅读更多优秀文章:凝神长老和他的朋友们(https://www.jxtxzzw.com)

也欢迎关注我的其他平台:知乎( https://s.zzw.ink/zhihu )、知乎专栏( https://s.zzw.ink/zhuanlan )、哔哩哔哩( https://s.zzw.ink/blbl )、微信公众号( 凝神长老和他的朋友们 )
凝神长老的二维码们

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凝神长老

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值