#include
#include
#include
#include
using namespace std;
const double eps = 1e-8;
const int maxn = 310;
struct node{
double len;
int cover;
}tree[8*maxn];
struct scanline{
double x, y1, y2;
int cover;
bool operator < (const scanline& another) const{
return x < another.x;
}
};
vector scanline_vector;
double segment_point[2*maxn];
void build(int left, int right, int root,int layer){
tree[root].cover = 0;
tree[root].len = 0;
if(left + 1 == right){
return;
}
int mid = left + ((right - left) >> 1);
build(left, mid, (root << 1) + 1, layer+1);
build(mid, right, (root << 1) + 2, layer+1);
}
void push_up(int index,int left,int right,int layer){
if(tree[index].cover != 0){
tree[index].len = segment_point[right] - segment_point[left];
}
else if(left + 1 == right){
tree[index].len = 0;
}else{
tree[index].len = tree[(index << 1) + 1].len + tree[(index << 1) + 2].len;
}
}
void update(int root, int rl, int rr, int left,int right, int cover,int layer){
if(left <= rl && right >= rr){
tree[root].cover += cover;
push_up(root, rl, rr,layer);
return;
}
if(rl + 1 == rr){
return;
}
int mid = rl + ((rr - rl) >> 1);
if(left <= mid){
update((root << 1) + 1, rl , mid, left, right, cover, layer+ 1);
}
if(right > mid){
update((root << 1) + 2, mid, rr, left, right,cover,layer+1);
}
push_up(root, rl, rr,layer);
}
int bsearch(double* array, double value, int l, int r){
int ll = l, rr = r;
if(ll == rr){
return ll;
}
while(ll <= rr){
int mid = ll + ((rr - ll) >> 1);
if(fabs(array[mid] - value) < eps){
return mid;
}
if(array[mid] < value){
ll = mid + 1;
}
else{
rr = mid - 1;
}
}
return ll;
}
int main() {
// freopen("1.txt","r",stdin);
int n;
int t = 1;
double leftx, lefty, rightx, righty;
while(scanf("%d", &n ) != EOF && n) {
memset(tree, 0, sizeof(tree));
scanline_vector.clear();
memset(segment_point, 0, sizeof(segment_point));
scanline_vector.resize(n << 1);
int cur = 0;
for(int i = 0; i < n; ++i){
scanf("%lf%lf%lf%lf",&leftx, &lefty, &rightx, &righty);
scanline_vector[(i << 1)].x = leftx;
scanline_vector[(i << 1)].y1 = lefty;
scanline_vector[(i << 1)].y2 = righty;
scanline_vector[(i << 1)].cover = 1;
scanline_vector[(i << 1) | 1].x = rightx;
scanline_vector[(i << 1) | 1].y1 = lefty;
scanline_vector[(i << 1) | 1].y2 = righty;
scanline_vector[(i << 1) | 1].cover = -1;
segment_point[cur++] = lefty;
segment_point[cur++] = righty;
}
//sort and unique segment_point
sort(segment_point, segment_point + cur);
int read_index = 1, write_index = 1;
while(read_index < cur){
if(segment_point[read_index - 1] != segment_point[read_index]){
segment_point[write_index++] = segment_point[read_index];
}
read_index++;
}
//segment_point valid length is write_index
//build segment_tree using discreeted segment_points
build(0, write_index - 1, 0, 1);
sort(scanline_vector.begin(), scanline_vector.end());
int size = scanline_vector.size();
double sum = 0;
for(int i = 0; i + 1 < size; i++){
int y1index = bsearch(segment_point, scanline_vector[i].y1, 0, write_index - 1);
int y2index = bsearch(segment_point, scanline_vector[i].y2, 0, write_index - 1);
update(0, 0, write_index - 1, y1index, y2index, scanline_vector[i].cover,1);
sum += (scanline_vector[i + 1].x - scanline_vector[i].x) * tree[0].len;
}
printf("Test case #%d\n", t++);
printf("Total explored area: %.2lf\n",sum);
printf("\n");
}
return 0;
}
coding时的错误:
1. 左右子结点的下标;
当root
下标为0时,右子结点是 (index << 1) + 2, 而不是(index<<1) | 2
2. 记得把freopen注释掉