跳至主要內容

Codeforces Round 817 (Div. 4) E. Counting Rectangles

AlgorithmCodeforces大约 1 分钟约 439 字全民制作人ikun

E. Counting Rectangles

image-20230415113917339 image-20230415113942127

题目大意

给你n个矩形和q组询问:n<=105,q<=105n<=10^5,q<=10^5

  • 每个矩形的长度为hi,wih_i,w_i,其中hi,wi<=1000h_i,w_i<=1000

  • 每组询问包含两个长宽,分别为hs,ws,hb,wbh_s,w_s,h_b,w_b

  • 问你这个长度能包含的矩形的面积和为多少,即hs<hi<hb,ws<wi<wbh_s<h_i<h_b,w_s<w_i<w_b

思路

因为长度和宽度的范围很小,因此我们可以使用二维前缀和算法,将长度和宽度的乘积存入对应的二维数组中去。然后对于每个询问,就相当于问在范围[hs+1,ws+1][hb1,wb1][h_s+1,w_s+1]~[h_b-1,w_b-1]之间的元素和为多少。

可参考二维前缀和模版,

注意这里对二维vector的使用:

如果是用vector<int> a[N]; 这种方式是不会对元素进行初始化的,因此在赋值的时候不可以使用+=

如果是使用 vector<vector<int>> a(N, vector<int>(N)); ,那么二维数组的元素初始化都是0

代码

#include <bits/stdc++.h>

#define int long long
using namespace std;
const int N = 1010;

void solve() {
    int n, q;
    cin >> n >> q;
    vector<vector<int>> a(N, vector<int>(N));
    vector<vector<int>> s(N, vector<int>(N));
    for (int i = 1; i <= n; i++) {
        int h, w;
        cin >> h >> w;
        a[h][w] += h * w;
    }
    for (int i = 1; i <= 1000; i++) {
        for (int j = 1; j <= 1000; j++) {
            s[i][j] = s[i - 1][j] + s[i][j - 1] + a[i][j] - s[i - 1][j - 1];
        }
    }
    while (q--) {
        int hs, ws, hb, wb;
        cin >> hs >> ws >> hb >> wb;
        int res = s[hb - 1][wb - 1] - s[hs][wb - 1] - s[hb - 1][ws] + s[hs][ws];
        cout << res << endl;
    }
}

signed main() {
#ifndef ONLINE_JUDGE
    freopen("../test.in", "r", stdin);
    freopen("../test.out", "w", stdout);
#endif
    int _;
    cin >> _;
    while (_--) solve();

    return 0;
}
上次编辑于:
贡献者: yunfeidog