二维差分求助,需要的话可以以关注为回报
查看原帖
二维差分求助,需要的话可以以关注为回报
760908
magic_dream楼主2023/1/16 21:05

大体思路是离散化二维差分,但由于对离散化理解不到位,实现上出现了点问题,想请教下各位哪里出了问题。如果的可以的话,想再请教下为什么左上角存进vector的时候坐标要减一,找下标的时候又加一。讨论区一位大佬写的二维差分我也看了就是没有太理解,就再来请教下。麻烦各位大佬了。

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 2e3 + 5;
const int M = 2e3 + 5;
const int inf = numeric_limits<int>::max();
const ll inff = numeric_limits<ll>::max();
const int mod = 1e9 + 7;
const double eps = 1e-10;
int n, m, k, cnt;
vector<int> nx, ny;//存点的坐标
array<int, 4> p[N];//记录左上角和右下角
int f[N][N];//记录覆盖
void solve() {
	cin >> n;
	for(int i = 1; i <= n; ++i) {
		int x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		p[i] = {x1, y1, x2, y2};
		nx.push_back(x1 - 1);
		ny.push_back(y1 - 1);
		nx.push_back(x2);
		ny.push_back(y2);
	}
	sort(nx.begin(), nx.end());//排序去重
	sort(ny.begin(), ny.end());
	nx.erase(unique(nx.begin(), nx.end()), nx.end());
	ny.erase(unique(ny.begin(), ny.end()), ny.end());
	for(int i = 1; i <= n; ++i) {
		auto [x1, y1, x2, y2] = p[i];
		x1 = lower_bound(nx.begin(), nx.end(), x1 - 1) - nx.begin() + 1;//找下标
		y1 = lower_bound(ny.begin(), ny.end(), y1 - 1) - ny.begin() + 1;
		x2 = lower_bound(nx.begin(), nx.end(), x2) - nx.begin();
		y2 = lower_bound(ny.begin(), ny.end(), y2) - ny.begin();
		f[x1][y1] += 1;//差分
		f[x2 + 1][y1] -= 1;
		f[x1][y2 + 1] -= 1;
		f[x2 + 1][y2 + 1] += 1;
	}
	int x = nx.size(), y = ny.size();
	for(int i = 1; i <= x; ++i)//前缀和
		for(int j = 1; j <= y; ++j)
			f[i][j] += f[i - 1][j];
	for(int i = 1; i <= x; ++i)
		for(int j = 1; j <= y; ++j)
			f[i][j] += f[i][j - 1];
	ll ans = 0;
	cout << '\n';
	for(int i = 1; i < x; ++i)
		for(int j = 1; j < y; ++j)
			if(f[i][j]) {//如果这里被覆盖了,就计算这个矩形的面积
				ans += (nx[i] - nx[i - 1]) * (ny[j] - ny[j - 1]);
			}
	cout << ans;
}	


int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	// int t;
	// cin >> t;
	// while(t--) 
		solve();
	return 0;
}
// 
// 
// 
// 
2023/1/16 21:05
加载中...