亚特兰蒂斯

#include <iostream>
#include <cstring>
#include <algorithm>
#include<vector>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e4 + 10;
int n;
struct query {
	double l, r;
	int k;
	double y;
	bool operator<(const query& e)const {
		return y < e.y;
	}
}q[2 * N];
vector<double> x;
int tc;
int find(double y) {
	return lower_bound(x.begin(), x.end(), y) - x.begin();
}
struct Node
{
	int l, r;
	double len;
	int cnt;
}tr[N * 8];

void pushup(int u)//重点!!!
{
	// TODO: 利用左右儿子信息维护当前节点的信息
	if (tr[u].cnt)tr[u].len = x[tr[u].r] - x[tr[u].l - 1];
	else if(tr[u].l!=tr[u].r){
		tr[u].len = tr[u << 1].len + tr[u << 1 | 1].len;
	}
	else tr[u].len = 0;//!!!
}

void build(int u, int l, int r)
{
	tr[u] = { l, r ,0,0};
	if(l!=r)
	{
		int mid = l + r >> 1;
		build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
	}
}

void modify(int u, int l, int r, int d)
{
	if (tr[u].l >= l && tr[u].r <= r)
	{
		// TODO: 修改区间
		tr[u].cnt += d;
		pushup(u);
	}
	else
	{
		int mid = tr[u].l + tr[u].r >> 1;
		if (l <= mid) modify(u << 1, l, r, d);
		if (r > mid) modify(u << 1 | 1, l, r, d);
		pushup(u);
	}
}

int main() {
	while (cin >> n, n) {
		double res = 0;
		int cnt = 0;
		x.clear();
		for (int i = 1; i <= n; i++) {
			double y1, y2, x1, x2;
			cin >> x1 >> y1 >> x2 >> y2;
			q[cnt++] = { x1,x2,1,y1 };
			q[cnt++] = { x1,x2,-1,y2 };
			x.push_back(x1), x.push_back(x2);
		}
		sort(q, q + 2 * n);
		sort(x.begin(), x.end());
		x.erase(unique(x.begin(), x.end()), x.end());

		build(1, 1, 2 * n - 1);
		for (int i = 0; i < 2 * n - 1 ; i++) {
			int x1 = find(q[i].l), x2 = find(q[i].r), k = q[i].k;
			modify(1, x1 + 1, x2, k);
			res += tr[1].len*(q[i+1].y-q[i].y);
		}
		printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++tc, res);
	}
}