POJ 1151

#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注释掉

你可能感兴趣的:(poj)