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\n", ++ca, ans);

	}

	return 0;

}

 

你可能感兴趣的:(FZU2187 回家种地(矩形面积并))