Codeforces-Round-817-Div-4-E-Counting-Rectangles


title: Codeforces Round 817 (Div. 4) E. Counting Rectangles
date: 2023-04-15 11:38:43
categories:

  • Algorithm
  • Codeforces
    tags:
  • codeforces
  • 前缀和
  • 二维前缀和
  • 1500

E. Counting Rectangles

image-20230415113917339 image-20230415113942127

题目大意

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

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

  • 每组询问包含两个长宽,分别为 h s , w s , h b , w b h_s,w_s,h_b,w_b hs,ws,hb,wb

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

思路

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

可参考二维前缀和模版,

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

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

如果是使用 vector<vector> a(N, vector(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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

重生之我是cxk

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

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

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

打赏作者

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

抵扣说明:

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

余额充值