扫描线

矩形面积并 (Atlantis)

View Code
#include<bits/stdc++.h>
using namespace std;

using lf = double;
using ll = long long;
using ull = unsigned long long;

const int maxn = 2e5 + 5; // two scan lines

struct scanline{
	lf y;
	lf left_x, right_x;
	int inout;
	scanline(){}
	scanline(lf y_, lf l, lf r, int io) : y(y_), left_x(l), right_x(r), inout(io) {}
} tree[maxn << 2];
int lazy_tag[maxn << 2];
lf length[maxn << 2], x[maxn];
int num, n, cnt, t = 0;

bool cmp(const scanline &a, const scanline &b) {return a.y < b.y;} // sort by y

ll ls(ll id) {return id << 1;}
ll rs(ll id) {return id << 1 | 1;}

void maintain(ll id, ll left, ll right) {
	if (lazy_tag[id]) length[id] = x[right] - x[left];
	else if (left + 1 == right) length[id] = 0; // leaf node
	else length[id] = length[ls(id)] + length[rs(id)];
}

void update(ll L, ll R, ll io, ll id = 1, ll left = 1, ll right = num) {
	if (L <= left and right <= R){
		lazy_tag[id] += io;
		maintain(id, left, right);
		return ;
	}
	if (left == right) return ;
	ll mid = (left + right) >> 1;
	if (L < mid) update(L, R, io, ls(id), left, mid);
	if (R > mid) update(L, R, io, rs(id), mid, right);
	maintain(id, left, right);
}

void solve() {
	cin >> n;
	if (!n) exit(0);
	cnt = 0;
	while (n--) {
		lf x1, x2, y_1, y_2;
		cin >> x1 >> y_1 >> x2 >> y_2;
		tree[++cnt] = {y_1, x1, x2, 1};
		x[cnt] = x1;
		tree[++cnt] = {y_2, x1, x2, -1};
		x[cnt] = x2;
	}

	sort(x + 1, x + cnt + 1);
	sort(tree + 1, tree + cnt + 1, cmp);

	num = unique(x + 1, x + cnt + 1) - (x + 1);
	memset(lazy_tag, 0, sizeof lazy_tag);
	memset(length, 0, sizeof length);

	lf ans = 0;

	for (int i = 1; i <= cnt; i++) {
		ans += length[1] * (tree[i].y - tree[i - 1].y);
		ll L = lower_bound(x + 1, x + num + 1, tree[i].left_x) - x;
		ll R = lower_bound(x + 1, x + num + 1, tree[i].right_x) - x;
		update(L, R, tree[i].inout);
	}

//Test case #1
//Total explored area: 180.00 

	cout << "Test case #" << ++t << "\n";
	cout << "Total explored area: " << fixed << setprecision(2) << ans << "\n\n";

}

int main() {

	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

//	freopen("T1.in", "r", stdin);
//	freopen("T1.out", "w", stdout);

	int T = 1;
//	cin >> T;
	while (T) solve();

	return 0;
} 

矩形周长并

View Code
#include <bits/stdc++.h>
using namespace std;

using lf = double;
using ll = long long;
using ull = unsigned long long;

const int maxn = 2e5 + 5;

struct scanline {
	int y;
	ll left_x, right_x;
	int inout;
	scanline() {}
	scanline(int y_, ll l, ll r, int io) : y(y_), left_x(l), right_x(r), inout(io) {}
} tree[maxn << 2];

int lazy_tag[maxn << 2];
ll length[maxn << 2];
ll cover_num[maxn << 2];
ll lcover[maxn << 2];
ll rcover[maxn << 2];
ll x[maxn];
int num, n, cnt;

bool cmp(const scanline &a, const scanline &b) {
	if (a.y != b.y) return a.y < b.y;
	return a.inout > b.inout;
}

ll ls(ll id) { return id << 1; }
ll rs(ll id) { return id << 1 | 1; }

void maintain(ll id, ll left, ll right) {
	if (lazy_tag[id]) {
		length[id] = x[right] - x[left];
		cover_num[id] = 1;
		lcover[id] = rcover[id] = 1;
	} else if (left + 1 == right) {
		length[id] = 0;
		cover_num[id] = 0;
		lcover[id] = rcover[id] = 0;
	} else {
		length[id] = length[ls(id)] + length[rs(id)];
		cover_num[id] = cover_num[ls(id)] + cover_num[rs(id)];
		if (rcover[ls(id)] and lcover[rs(id)])
			cover_num[id]--;
		lcover[id] = lcover[ls(id)];
		rcover[id] = rcover[rs(id)];
	}
}

void update(ll L, ll R, ll io, ll id = 1, ll left = 1, ll right = num) {
	if (L <= left and right <= R) {
		lazy_tag[id] += io;
		maintain(id, left, right);
		return;
	}
	if (left + 1 == right) return;
	ll mid = (left + right) >> 1;
	if (L < mid) update(L, R, io, ls(id), left, mid);
	if (R > mid) update(L, R, io, rs(id), mid, right);
	maintain(id, left, right);
}

void solve() {
	cin >> n;
	cnt = 0;
	for (int i = 0; i < n; i++) {
		int x1, x2, y_1, y_2;
		cin >> x1 >> y_1 >> x2 >> y_2;
		tree[++cnt] = {y_1, x1, x2, 1};
		x[cnt] = x1;
		tree[++cnt] = {y_2, x1, x2, -1};
		x[cnt] = x2;
	}
	
	sort(x + 1, x + cnt + 1);
	num = unique(x + 1, x + cnt + 1) - (x + 1);
	
	sort(tree + 1, tree + cnt + 1, cmp);
	
	memset(lazy_tag, 0, sizeof(lazy_tag));
	memset(length, 0, sizeof(length));
	memset(cover_num, 0, sizeof(cover_num));
	memset(lcover, 0, sizeof(lcover));
	memset(rcover, 0, sizeof(rcover));
	
	ll ans = 0;
	ll last_length = 0;
	
	for (int i = 1; i <= cnt; i++) {
		
		ll L = lower_bound(x + 1, x + num + 1, tree[i].left_x) - x;
		ll R = lower_bound(x + 1, x + num + 1, tree[i].right_x) - x;
		
		
		update(L, R, tree[i].inout);
		ans += cover_num[1] * 2 * (tree[i + 1].y - tree[i].y);
		ans += abs(length[1] - last_length);
		
		last_length = length[1];
	}
	
	cout << ans << "\n";
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	
	// freopen("T1.in", "r", stdin);
	// freopen("T1.out", "w", stdout);
	
	int T = 1;
	// cin >> T;
	while (T--) solve();
	
	return 0;
}
posted @ 2025-12-19 21:23  Yangyihao  阅读(2)  评论(0)    收藏  举报