HDU1542 Atlantis(矩形面积并)

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

int n;
struct Segment
{
	double l, r, x;
	int li, ri;
	bool isleft;
	bool operator < (const Segment &b) const{
		return x < b.x;
	}
}s[maxn*3];

int top;
double ydis[800];
int ytop = 0;

struct Node
{
	int cov;
	int l, r;
	double len;
}N[3000];


void build(int i, int L, int R)
{
	N[i].cov = 0;
	N[i].l = L; N[i].r = R;
	N[i].len = ydis[R] - ydis[L];
	if (N[i].r-N[i].l<=1){
		return;
	}
	int M = (L + R) >> 1;
	build(i << 1, L, M);
	build(i << 1 | 1, M, R);
}

void pushDown(int i)
{
	if (N[i].r-N[i].l<=1) return;
	if (N[i].cov!=0){
		N[i << 1].cov += N[i].cov;
		N[i << 1 | 1].cov += N[i].cov;
		N[i].cov = 0;
	}
}

void add(int i, int L, int R,int val)
{
	if (N[i].l == L&&N[i].r == R){
		N[i].cov += val;
		return;
	}
	pushDown(i);
	int M = (N[i].l + N[i].r) >> 1;
	if (R <= M) add(i << 1, L, R, val);
	else if (L >= M) add(i << 1 | 1, L, R, val);
	else {
		add(i << 1, L, M, val);
		add(i << 1 | 1, M, R, val);
	}
}

double query(int i)
{
	pushDown(i);
	if (N[i].r - N[i].l <= 1&&N[i].cov>0) return N[i].len;
	else if (N[i].r - N[i].l <= 1) return 0;
	return query(i << 1) + query(i << 1 | 1);
}

int main()
{
	int ca = 0;
	while (cin >> n&&n)
	{
		double x1, y1, x2, y2; top = 0; ytop = 0;
		for (int i = 0; i < n; i++){
			scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
			s[top].x = x1; s[top].l = y1; s[top].r = y2; s[top++].isleft = true;
			s[top].x = x2; s[top].l = y1; s[top].r = y2; s[top++].isleft = false;
			ydis[ytop++] = y1; ydis[ytop++] = y2;
		}
		sort(ydis, ydis + ytop);
		ytop = unique(ydis, ydis + ytop) - ydis;
		sort(s, s + top);
		for (int i = 0; i < top; i++){
			s[i].li = lower_bound(ydis, ydis + ytop, s[i].l) - ydis;
			s[i].ri = lower_bound(ydis, ydis + ytop, s[i].r) - ydis;
		}
		ydis[ytop] = ydis[ytop - 1];
		build(1, 0, ytop); double ans = 0;double lx = s[0].x;
		for (int i = 0; i < top; i++){
			ans += query(1)*(s[i].x - lx);
			if (s[i].isleft){
				add(1, s[i].li, s[i].ri ,1);
			}
			else{
				add(1, s[i].li, s[i].ri, -1);
			}
			lx = s[i].x;
		}
		printf("Test case #%d
", ++ca);
		printf("Total explored area: %.2lf
", ans);
		puts("");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/chanme/p/3621905.html