hdu1542Atlantis(线段树+扫描线)

题目描述:

Atlantis

Problem Description
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to know the total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity.
 题意:求矩形面积得并集

 思路:与之前写的那个求面积交集的相似,而且更简单,这题只需要求覆盖的面积即可,那道题是覆盖次数大于1的面积(交集),

还要多一个sum变量,所以这题就不多说了,一样的模板,更低的难度,要看懂代码的可以先去看我那题的题解,传送门

 

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 210;
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define ls(x) x<<1
#define rs(x) x<<1|1
struct node {
    int l, r, cnt;
    double sum;
}tree[maxn<<2];
struct p {
    double x1, x2, h;
    int f;
    p() {};
    p(double a, double b, double c, int q) :x1(a), x2(b), h(c), f(q) {};
    bool operator<(p b)const {
        return h < b.h;
    }
}e[maxn];
int num;
double x[maxn];
void build(int rt, int l, int r) {
    tree[rt].l = l, tree[rt].r = r;
    tree[rt].cnt = tree[rt].sum = 0;
    if (l == r)return;
    int mid = (l + r) >> 1;
    build(lson);
    build(rson);
}
void push_up(int rt) {
    int l = tree[rt].l, r = tree[rt].r;
    if (tree[rt].cnt) {//如果懒标记存在(这个区间都被覆盖了),就直接是这个区间的长度
        tree[rt].sum = x[r + 1] - x[l];
    }
    else if(l==r){//叶子节点,其实要不是有多组数据,叶子节点的孩子的sum可能是之前的数据而不是0,不然这个if也不用要
        tree[rt].sum = 0;
    }
    else {//两个孩子的覆盖区间长度的和
        tree[rt].sum = tree[ls(rt)].sum + tree[rs(rt)].sum;
    }
}
void update(int rt, int L, int R, int f) {
    if (L <= tree[rt].l && tree[rt].r <= R) {
        tree[rt].cnt += f;//懒标记
        push_up(rt);
        return;
    }
    int mid = (tree[rt].l + tree[rt].r) >> 1;
    if (L <= mid) {
        update(ls(rt), L, R, f);
    }
    if (R > mid) {
        update(rs(rt), L, R, f);
    }
    push_up(rt);
}
int main() {
    //freopen("test.txt", "r", stdin);
    int n;
    int t = 0;
    while (scanf("%d", &n) && n) {
        t++;
        num = 0;
        while (n--) {
            double x1, x2, y1, y2; scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            e[++num] = { x1,x2,y1,1 };
            x[num] = x1;
            e[++num] = { x1,x2,y2,-1 };
            x[num] = x2;
        }
        sort(e + 1, e + num + 1);
        sort(x + 1, x + num + 1);
        int cnt = unique(x + 1, x + num + 1) - x - 1;//离散化
        build(1, 1, cnt);//初始化,要不然就直接memset
        double ans = 0;
        for (int i = 1; i < num; i++) {
            int l = lower_bound(x + 1, x + cnt + 1, e[i].x1) - x;
            int r = lower_bound(x + 1, x + cnt + 1, e[i].x2) - x - 1;
            update(1, l, r, e[i].f);
            ans += tree[1].sum * (e[i + 1].h - e[i].h);//这里不再说了
        }
        printf("Test case #%d\n", t);
        printf("Total explored area: %.2lf\n", ans);
        printf("\n");
    }
    return 0;
}

 

posted @ 2021-03-26 22:24  cono奇犽哒  阅读(51)  评论(0)    收藏  举报