#include <iostream> #include <algorithm> using namespace std; #define MAX 101 #define INF 100001.0f struct TNode { int left, right; double top; double sum; }; TNode T[MAX*12]; double map[MAX][4];// left right bolow high double temp[MAX*2]; int index; double sum; int find(double v) { int low = 0, high = index-1; while(low <= high) { int mid = (low + high) >> 1; if(v == temp[mid]) return mid; else if(v > temp[mid]) low = mid + 1; else high = mid - 1; } return 0; } void build(int s, int t, int step) { T[step].left = s; T[step].right = t; T[step].top = -1.0f; T[step].sum = 0.0f; if(t -s <= 1) return; int mid = (s + t) >> 1; build(s, mid, step*2); build(mid, t, step*2+1); } void insert(int s, int t, int step, double below, double high) { if(T[step].right -T[step].left <= 1) { if(below > T[step].top) { T[step].sum += (high - below)*(temp[T[step].right] - temp[T[step].left]); T[step].top = high; } else if(high > T[step].top) { T[step].sum += (high - T[step].top)*(temp[T[step].right] - temp[T[step].left]); T[step].top = high; } return; } int mid = (T[step].left + T[step].right) >> 1; if(t <= mid) insert(s, t, step*2, below, high); else if(mid <= s) insert(s, t, step*2+1, below, high); else { insert(s, mid, step*2, below, high); insert(mid, t, step*2+1, below, high); } } void calculate(int step) { if(T[step].right -T[step].left <= 1) { if(T[step].sum != 0.0f) sum += T[step].sum; return; } calculate(step*2); calculate(step*2+1); } int cmp(const void* lhs, const void* rhs) { if( ((double*)lhs)[2] < ((double*)rhs)[2] ) return -1; return 1; } int main() { int n; int cnt = 0; while(scanf("%d", &n) && n) { sum = 0.0f; index = 0; for(int i = 0; i < n; ++i) {// left below right high scanf("%lf%lf%lf%lf",&map[i][0], &map[i][2], &map[i][1], &map[i][3]); temp[index++] = map[i][0]; temp[index++] = map[i][1]; } sort(temp, temp+2*n); index = 1; for(int i = 1; i < 2*n; ++i) // 去除重复点 if(temp[i] != temp[i-1]) temp[index++] = temp[i]; qsort(map, n, 4*sizeof(double),cmp); build(0, index-1, 1); for(int i = 0; i < n; ++i) insert(find(map[i][0]), find(map[i][1]), 1, map[i][2], map[i][3]); calculate(1); printf("Test case #%d/nTotal explored area: %.2lf/n/n", ++cnt, sum); } return 0; } 插入到线段树的时间复杂度O(N*logN*logN), 故算法的复杂度为: O(N*logN^2)