HDU 1255 覆盖的面积(线段树+离散化+扫描线)

来源:互联网 发布:调光手电筒软件 编辑:程序博客网 时间:2024/06/05 10:25

题目分析

上次做了一道只用计算覆盖一次的面积,这次需要计算覆盖2次的面积,其实就是在上面的基础上加一点东西,sum1[]表示覆盖一次的长度,sum2[]覆盖2次的长度,具体怎么操作看pushup函数即可,写的非常清楚。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define mid (L+R)/2#define lson o<<1, L, mid#define rson o<<1|1, mid+1, Rconst int maxn = 2005;double pos[maxn<<2];double sum1[maxn<<2], sum2[maxn<<2];  //sum1表示覆盖一次的长度,sum2表示覆盖2次的长度int flag[maxn<<2];struct Edge{    double l, r, h;    int f;    Edge(){}    Edge(double a, double b, double c, int d):l(a), r(b), h(c), f(d){}    bool operator < (const Edge& e)const{        return h < e.h;    }}line[maxn];void pushup(int o,int L,int R){   //这里代码已经写得很清楚了    if(flag[o]) sum1[o] = pos[R+1] - pos[L];        else if(L == R) sum1[o] = 0;    else sum1[o] = sum1[o<<1] + sum1[o<<1|1];    if(flag[o] > 1) sum2[o] = pos[R+1] - pos[L];    else if(L == R) sum2[o] = 0;    else if(flag[o] == 1) sum2[o] = sum1[o<<1] + sum1[o<<1|1];    else sum2[o] = sum2[o<<1] + sum2[o<<1|1];}void update(int o,int L,int R,int l,int r,int val){ //更新    if(l <= L && R <= r){        flag[o] += val;        pushup(o, L, R);        return;    }    if(l <= mid) update(lson, l, r, val);    if(r > mid) update(rson, l, r, val);    pushup(o, L, R);}int BS(double k, double a[], int len){  //二分查找    int L = 0, R = len-1;    while(L <= R){        if(a[mid] == k) return mid;        else if(a[mid] < k) L = mid+1;        else R = mid-1;    }    return -1;}int main(){    int T, n;    scanf("%d", &T);    while(T--){        memset(sum1, 0, sizeof(sum1));        memset(sum2, 0, sizeof(sum2));        memset(flag, 0, sizeof(flag));        memset(pos, 0, sizeof(pos));        double x1, y1, x2, y2;        scanf("%d", &n);        int k = 0;        for(int i = 0; i < n; i++){            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);            pos[k] = x1;            line[k++] = Edge(x1, x2, y1, 1);            pos[k] = x2;            line[k++] = Edge(x1, x2, y2, -1);        }        sort(pos, pos+k);        sort(line, line+k);        int m = 1;        for(int i = 1; i < k; i++)            if(pos[i] != pos[i-1]) pos[m++] = pos[i];        double ans = 0;        for(int i = 0; i < k-1; i++){            int l = BS(line[i].l, pos, m);            int r = BS(line[i].r, pos, m)-1;            update(1, 0, k-1, l, r, line[i].f);            ans += sum2[1]*(line[i+1].h - line[i].h);        }        printf("%.2lf\n", ans);    }    return 0;}
0 0
原创粉丝点击