hdu 3265 Posters(扫描线)

题目链接:hdu 3265 Posters

题目大意:就是给定N个矩形,矩形比较特殊,均被减掉了一部分,问说图形最后的覆盖面积。

解题思路:一开始做的时候以为直接做扫描线就好了,一个做加的一个做减的,后来写完样例都跑不出来,还是对扫描线理解的不够深刻,因为扫描线没有pushdown的操作,因为它肯定对于每段区间有加有减,那么如果碰到一开始就是减的,就没法做了。

正解是将一个图形差分成至多4个小的矩形表示,然后直接扫描线。

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

const int maxn = 50005;

#define lson(x) ((x)<<1)
#define rson(x) (((x)<<1)|1)
int lc[maxn << 2], rc[maxn << 2], v[maxn << 2], s[maxn << 2];

inline void pushup (int u) {
    if (v[u])
        s[u] = rc[u] - lc[u] + 1;
    else if (rc[u] == lc[u])
        s[u] = 0;
    else
        s[u] = s[lson(u)] + s[rson(u)];
}

inline void maintain (int u, int d) {
    v[u] += d;
    pushup(u);
}

void build (int u, int l, int r) {
    lc[u] = l;
    rc[u] = r;
    s[u] = v[u] = 0;

    if (l == r)
        return ;

    int mid = (l + r) / 2;
    build(lson(u), l, mid);
    build(rson(u), mid + 1, r);
    pushup(u);
}

void modify (int u, int l, int r, int d) {
    if (l <= lc[u] && rc[u] <= r) {
        maintain(u, d);
        return;
    }

    int mid = (lc[u] + rc[u]) / 2;
    if (l <= mid)
        modify(lson(u), l, r, d);
    if (r > mid)
        modify(rson(u), l, r, d);
    pushup(u);
}

struct Seg {
    int x, l, r, d;
    Seg (int x = 0, int l = 0, int r = 0, int d = 0) {
        this->x = x;
        this->l = l;
        this->r = r;
        this->d = d;
    }
};

typedef long long ll;

int N;
vector<Seg> vec;

inline bool cmp (const Seg& a, const Seg& b) {
        return a.x < b.x;
}

inline void add (int x1, int y1, int x2, int y2) {
    if (y1 == y2 || x1 == x2)
        return;
    vec.push_back(Seg(x1, y1, y2 - 1, 1));
    vec.push_back(Seg(x2, y1, y2 - 1, -1));
}

void init () {
    int x1, x2, x3, x4;
    int y1, y2, y3, y4;

    scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    scanf("%d%d%d%d", &x3, &y3, &x4, &y4);
    add (x1, y1, x2, y3);
    add (x1, y3, x3, y4);
    add (x4, y3, x2, y4);
    add (x1, y4, x2, y2);
}

int main () {
    while (scanf("%d", &N) == 1 && N) {
        build(1, 0, 50000);
        vec.clear();
        for (int i = 0; i < N; i++)
            init();
        sort(vec.begin(), vec.end(), cmp);

        ll ans = 0;
        for (int i = 0; i < vec.size(); i++) {
            modify(1, vec[i].l, vec[i].r, vec[i].d);
            if (i != vec.size() - 1)
                ans += 1LL * s[1] * (vec[i+1].x - vec[i].x);
        }
        printf("%I64d\n", ans);
    }
    return 0;
}
时间: 2024-08-28 17:23:48

hdu 3265 Posters(扫描线)的相关文章

(中等) HDU 3265 Posters , 扫描线。

Problem Description Ted has a new house with a huge window. In this big summer, Ted decides to decorate the window with some posters to prevent the glare outside. All things that Ted can find are rectangle posters. However, Ted is such a picky guy th

HDU 3265 Posters(线段树)

HDU 3265 Posters 题目链接 题意:给定一些矩形海报,中间有孔,求贴海报的之后的海报覆盖面积并 思路:海报一张可以切割成4个矩形,然后就是普通的矩形面积并了,利用线段树维护即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int N = 50005; struct Node { i

HDU 3265 Posters (线段树+扫描线)(面积并)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265 给你n个中间被挖空了一个矩形的中空矩形,让你求他们的面积并. 其实一个中空矩形可以分成4个小的矩形,然后就是面积并,特别注意的是x1 == x3 || x2 == x4的时候,要特判一下,否则会RE. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algori

HDU 3265 Posters(线段树扫描线&#183;矩形框面积并)

题意  把一些矩形海报挖去一部分小矩形贴在指定位置  问最后海报覆盖的面积 一个矩形框可以分割成4个独立的小矩形  然后就能用扫描线求面积并了 #include <cstdio> #include <algorithm> using namespace std; const int N = 100005, M = N << 2; typedef long long ll; struct SLine { int x, y1, y2, flag; SLine() {}; S

HDU 3265 Posters ——(线段树+扫描线)

第一次做扫描线,然后使我对线段树的理解发生了动摇= =..这个pushup写的有点神奇.代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #define t_mid (l+r>>1) 5 #define ls (o<<1) 6 #define rs (o<<1|1) 7 #define lson ls,l,t_mid 8 #define

hdu 3265 Posters

///给你若干个没有交集的圆,以其中一个圆的圆心为圆心做一个圆 ///使得这个圆至少包含所有圆面积的一半,求这个圆最小的半径 # include <stdio.h> # include <algorithm> # include <iostream> # include <string.h> # include <math.h> #include <string> using namespace std; struct node {

HDU 1255 离散化+扫描线覆盖的面积

覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3571    Accepted Submission(s): 1753 Problem Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据

HDU 3265 扫描线(矩形面积并变形)

Posters Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5230    Accepted Submission(s): 1220 Problem Description Ted has a new house with a huge window. In this big summer, Ted decides to decora

hdu 3255 Farming(扫描线)

题目链接:hdu 3255 Farming 题目大意:给定N个矩形,M个植物,然后给定每一个植物的权值pi,pi表示种植物i的土地,单位面积能够收获pi,每一个矩形给定左下角和右上角点的坐标,以及s,s表示该矩形能够中植物s.问说总的最大收益. 解题思路:由于一块仅仅能种一种植物,所以对于一块重叠的土地,要选取收益最大的植物种植.除去这一点,剩下的就是线段树扫描线的应用了.那对于pi能够视为第三维坐标,而植物的种类仅仅有3种,所以直接离散化就可以,注意要依照植物收益的权值大小离散. #inclu