FZU2187 回家种地(矩形面积并)

矩形面积并(只覆盖一次的面积)的裸题。好久没写代码debug了我太久,太辛酸了。

#pragma warning(disable:4996)
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

#define ll long long
#define maxn 200005
#define y1 y111

int lf[maxn << 2], rf[maxn << 2];
int sum[maxn << 2];
int a[maxn];
int add[maxn << 2];
int mi[maxn << 2];
int ma[maxn << 2];

int n, nSize;

void pushUp(int i)
{
	mi[i] = min(mi[i << 1], mi[i << 1 | 1]);
	ma[i] = max(ma[i << 1], ma[i << 1 | 1]);
}

void pushDown(int i)
{
	if (add[i] != 0){
		if (lf[i] != rf[i]){
			add[i << 1] += add[i];
			add[i << 1 | 1] += add[i];
			mi[i << 1] += add[i];
			ma[i << 1] += add[i];
			mi[i << 1 | 1] += add[i];
			ma[i << 1 | 1] += add[i];
			add[i] = 0;
		}
	}
}

void build(int i, int L, int R)
{
	lf[i] = L; rf[i] = R; add[i] = mi[i] = ma[i] = 0;
	if (L == R){
		sum[i] = a[L];
		return;
	}
	int M = (L + R) >> 1;
	build(i << 1, L, M);
	build(i << 1 | 1, M + 1, R);
	sum[i] = sum[i << 1] + sum[i << 1 | 1];
}

void upd(int i, int L, int R,int v)
{
	if (L == lf[i] && R == rf[i]){
		add[i] += v;
		mi[i] += v;
		ma[i] += v;
		return;
	}
	pushDown(i);
	int M = (lf[i] + rf[i]) >> 1;
	if (R <= M){
		upd(i << 1, L, R,v);
	}
	else if (L > M){
		upd(i << 1 | 1, L, R, v);
	}
	else{
		upd(i << 1, L, M, v);
		upd(i << 1 | 1, M + 1, R, v);
	}
	pushUp(i);
}

ll query(int i)
{
	if (ma[i] <= 0) return 0;
	if (mi[i] > 1) return 0;
	if (ma[i] == mi[i] && ma[i] == 1){
		return sum[i];
	}
	pushDown(i);
	return query(i << 1) + query(i << 1 | 1);
}

struct Node
{
	ll x;
	ll bg, ed;
	int v;
	Node(ll xi, ll bgi, ll edi,int vi) :x(xi), bg(bgi), ed(edi),v(vi){}
	bool operator < (const Node &b)const{
		return x == b.x ? v>b.v : x < b.x;
	}
};
vector<Node> vec;
vector<ll> dis;

int main()
{
	int T; cin >> T; int ca = 0;
	while (T--)
	{
		scanf("%d", &n);
		ll x1, x2, y1, y2;
		vec.clear();
		vec.reserve(2 * n + 100);
		dis.clear();
		for (int i = 0; i < n; ++i){
			scanf("%I64d%I64d%I64d%I64d", &x1, &y1, &x2, &y2);
			vec.push_back(Node(x1, y1, y2,1));
			vec.push_back(Node(x2, y1, y2,-1));
			dis.push_back(y1);
			dis.push_back(y2);
		}
		sort(dis.begin(), dis.end());
		nSize = unique(dis.begin(), dis.end()) - dis.begin();
		for (int i = 1; i < nSize; ++i){
			a[i] = dis[i] - dis[i - 1];
		}
		for (int i = 0; i < vec.size(); ++i){
			int lid = lower_bound(dis.begin(), dis.begin()+nSize, vec[i].bg) - dis.begin();
			int rid = lower_bound(dis.begin(), dis.begin()+nSize, vec[i].ed) - dis.begin();
			vec[i].bg = lid + 1;
			vec[i].ed = rid;
		}
		sort(vec.begin(), vec.end());
		build(1, 1, nSize - 1);

		ll ans = 0;
		ll preLen = 0;
		ll prex = vec[0].x;
		for (int i = 0; i < vec.size(); ++i){
			ll val = vec[i].x;
			while (i<vec.size()&&vec[i].x == val){
				upd(1, vec[i].bg, vec[i].ed, vec[i].v);
				++i;
			}
			--i;
			ans += preLen*(vec[i].x - prex);
			prex = vec[i].x;
			preLen = query(1);
		}
		printf("Case %d: %I64d
", ++ca, ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/chanme/p/4357825.html