CF1722E Counting Rectangles(div4)

53 阅读2分钟

Problem - 1722E - Codeforces

我寻思复健暂时从简单的题开始,于是我便找到了这个div4div4EE题,结果大失所望,我现在连div4div4EE都做不了,我该取s了。

题目在luoguluogu大佬的翻译变成了如下的一段话:

Counting Rectangles

题面翻译

分别给定 nn 个正整数 hi,wih_i,w_i ,有 qq 次询问。

对于每次询问,输入四个整数 hs,ws,hb,wbh_s,w_s,h_b,w_b,输出满足 hi(hs,hb)h_i \in (h_s,h_b) ,wi(ws,wb)w_i\in(w_s,w_b)hiwi\sum h_i \cdot w_i

输入格式

The first line of the input contains an integer tt ( 1t1001 \leq t \leq 100 ) — the number of test cases.

The first line of each test case two integers n,qn, q ( 1n1051 \leq n \leq 10^5 ; 1q1051 \leq q \leq 10^5 ) — the number of rectangles you own and the number of queries.

Then nn lines follow, each containing two integers hi,wih_i, w_i ( 1hi,wi10001 \leq h_i, w_i \leq 1000 ) — the height and width of the ii -th rectangle.

Then qq lines follow, each containing four integers hs,ws,hb,wbh_s, w_s, h_b, w_b ( 1hs<hb, ws<wb10001 \leq h_s < h_b,\ w_s < w_b \leq 1000 ) — the description of each query.

The sum of qq over all test cases does not exceed 10510^5 , and the sum of nn over all test cases does not exceed 10510^5 .

输出格式

For each test case, output qq lines, the ii -th line containing the answer to the ii -th query.

样例 #1

样例输入 #1

3
2 1
2 3
3 2
1 1 3 4
5 5
1 1
2 2
3 3
4 4
5 5
3 3 6 6
2 1 4 5
1 1 2 10
1 1 100 100
1 1 3 3
3 1
999 999
999 999
999 998
1 1 1000 1000

样例输出 #1

6
41
9
0
54
4
2993004

提示

In the first test case, there is only one query. We need to find the sum of areas of all rectangles that can fit a 1×11 \times 1 rectangle inside of it and fit into a 3×43 \times 4 rectangle.

Only the 2×32 \times 3 rectangle works, because 1<21 < 2 (comparing heights) and 1<31 < 3 (comparing widths), so the 1×11 \times 1 rectangle fits inside, and 2<32 < 3 (comparing heights) and 3<43 < 4 (comparing widths), so it fits inside the 3×43 \times 4 rectangle. The 3×23 \times 2 rectangle is too tall to fit in a 3×43 \times 4 rectangle. The total area is 23=62 \cdot 3 = 6 .

分析

我开始又在想二分,蚌埠住了,后来发现不是单调性,没法二分,然后我就不会做了,你怎么这么快啊,于是发现这其实是一个二维前缀和的板子,没法再简单了,就当是复习一下二维前缀和吧。。。这里要注意要把输入的前区间++++,后区间--。因为是开区间,欧了就。。。

代码

#include <bits/stdc++.h>

#define ll long long
#define x first
#define y second

using namespace std;
const int N=1010;
ll s[N][N];
int n,q;
void solve(){
	cin>>n>>q;
	memset(s,0,sizeof s);
	for(int i=1;i<=n;i++){
		ll h,w;
		cin>>h>>w;
		s[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]-s[i-1][j-1]; 
		} 
	}
	while(q--){
		int l1,r1,l2,r2;
		cin>>l1>>r1>>l2>>r2;
		l1++;r1++;l2--;r2--; 
		cout<<s[l2][r2]-s[l1-1][r2]-s[l2][r1-1]+s[l1-1][r1-1]<<"\n";
	}
//	while(q--){
//		int l1,r1,l2,r2;
//		cin>>l1>>r1>>l2>>r2;
//		l1++;r1++;l2--;r2--;
//		cout<<s[l1][r2]-s[l1-1][r2]-s[l2][r1-1]+s[l1-1][r1-1]<<"\n";
//	}
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int t;
	cin>>t;
	while(t--){
		solve();
		
	}
	return 0;
}