Poj1151——Atlantis

Poj1151 - Atlantis (Acwing247 Atlantis.)

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.

Input

The input consists of several test cases. Each test case starts with a line containing a single integer n (1 <= n <= 100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.
The input file is terminated by a line containing a single 0. Don't process it.

Output

For each test case, your program should output one section. The first line of each section must be "Test case #k", where k is the number of the test case (starting with 1). The second one must be "Total explored area: a", where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point.
Output a blank line after each test case.

Sample Input

2
10 10 20 20
15 15 25 25.5
0

Sample Output

Test case #1
Total explored area: 180.00 

scan line segment tree + + + discrete binary

my first channel scan line, and I think this question is very hard but also very troublesome, it is also easy to record it after the review.

n ranges from the relatively small poj 100 only, in fact, the problem in a scan line, then the range can be expanded to the level of n 1e5 (which may be submitted to the Acwing https://www.acwing.com/problem/content/249/ there are Chinese problems surface)

title mean to be determined in the plane give us some rectangle (rectangle input vertex and the upper right corner of the top left vertex), let us count these rectangles public area.

You can do with the scanning lines. We use a straight line parallel to the y-axis to the right start translation from the first point, in fact, can be used in the practice area of ideas of calculus, is actually two adjacent x multiplied within each range segment of length h, h we can use this to maintain the tree line.
How to maintain it, because the scanning process conducted online, for the same rectangle, certainly after two of its sides, for the first time entering the rectangular area, and the second is to leave the rectangular area, for each rectangle, we define when read right to left it a value of 1, the right to the right of the value of -1,
so that each segment is greater than in the tree after the interval 0 is that we modify the requirements h, then it can be maintained within the segment tree a CNT (notation is lazy, that the maintenance interval length of the node is greater than 0, if more than necessary to add, if not equal to 0 plus) and len recording interval length of the node. (Scanning line of thought, good clever ah!)


(Yxc Gangster map, the very image)


The question then converted into a question of amending + range query with tree line interval. But so lazy compare very difficult to write, this time we can use nature of the scan lines, no lazy below. Because of the tree line in operation lazy decentralization it is split when the current interval will lazy pushdown to child nodes, and query and modify the scanning lines are not split node problem, so no pushdown. 
Proof: 1, when the query we want to get is a whole range len, that is the root of len, do not need to split.
2, the line segment for each rectangle with weights in pairs when modify, so I do not need to split. (This is more difficult to understand and more specific, you can directly remember, some properties of the scan line problem)
then this problem would not have lazy converted into the bottom of the tree line, knocking it will be a little easier. (! Although not this just the nature of hard knocks pushdown can be achieved directly, but to write a lot of trouble, yysy this question does not have under the lazy difficult knocked ah)

caveats: 1, we read came a point , while the segment tree maintenance is the interval, so the build and modify the time interval should pay attention to the need to deal with it.
2, the coordinates of this question the existence of floating-point numbers, then we must use to discrete + half to record the coordinates.

Some pits point: The final output of this question to the extra output a blank line (a topic people are really not insane person ah) as well as knock when really annoying (this code is the ability to clog konjac tcl)

Summary: Since yesterday evening after looking at this question, read the explanation yxc Gangster dawned think you know, but the knock on board found that there are a lot of details difficult to solve (such as below lazy to write them annoying, pushup is not good writing, segment tree relationship maintenance interval and storage point need to be converted) and weak weak to see yxc Gangster explanation
after reading or Sidongfeidong (tcl), the storm was not directly to sleep. During the day and friends climb RENHUANGSHAN, as if returning to the sport to get my head around a little bit faster? (Home quarantine 14 days I really want to sleep silly) questions make up this evening. The first channel scanning lines, in memory of, to prevent over time to forget.

Attach Code:
#include <cstdio> 
#include <algorithm> 
#include <CString> 
#include <the Vector>
 // use c ++ submit this question to submit poj attention! G ++ will be submitted with WA
 // Note also that the assignment of the structure can not directly be CE = {} ......

using namespace std;
const int N = 1e5 + 5;
int n, m;
vector<double> ys;

struct Segment{
    double x, y1, y2;
    int k;
}seg[N << 1];

bool cmp(Segment a, Segment b) {
    return a.x < b.x;
}

struct node {
    int l, r;
    int cnt;
    double len;
}tr[N << 3];

int find(double y) {
    return lower_bound(ys.begin(), ys.end(), y) - ys.begin();
}

void pushup ( int U) {   // This pushup beginning I think quite hard to understand 
    IF (TR [U] .cnt) TR [U] .LEN = YS [TR [U] .r + 1 ] - YS [TR [U] .L];
     the else  IF (! TR [U] .L = TR [U] .r) {
        tr [u] .len = tr [u << 1 ] .len + tr [u << 1 | 1 ] .len;
    } else {
        p [u] .len = 0 ;
    }
}

void build(int u, int l, int r) {
    tr[u] = {l, r, 0, 0};  //初始化时都是0,所以也不要pushup
//    tr[u].l = l;
//    tr[u].r = r;
//    tr[u].cnt = 0;
//    tr[u].len = 0;
    if (l != r) {
        int mid = l + r >> 1;
        if (l <= mid) build(u << 1, l, mid);
        if (r > mid) build(u << 1 | 1, mid + 1, r);
    }
}

void Modify ( you and, you're the, you're down, you k)
{
    if (tr[u].l >= l && tr[u].r <= r)
    {
        p [u] .cnt + = k;
        pushup(u);
    }
    else
    {
        int mid = tr[u].l + tr[u].r >> 1;
        if (l <= mid) modify(u << 1, l, r, k);
        if (r > mid) modify(u << 1 | 1, l, r, k);
        pushup(u);
    }
}

int main ()
{
    int cas = 0;
    while (scanf("%d", &n) != EOF) {
        if (n == 0) break;
        double x1, x2, y1, y2;
        for (int i = 0, j = 0; i < n; ++i) {
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            SEG [J ++] = {X1, Y1, Y2, . 1 };    //   first the edge, it is the value +1 weight 
            SEG [J ++] = {X2, Y1, Y2, - . 1 };   //   change the pattern edge, so that the weight -1
 //             SEG [J] .x = X1; SEG [J] = Y1 .y1; SEG [J] = Y2 .Y2; SEG [J] = .K. 1;        //  
/ /             J ++;
 //             SEG [J] .x = X2; SEG [J] = Y1 .y1; SEG [J] = Y2 .Y2; SEG [J] = -1 .K;
 //             J ++; 
            ys.push_back ( y1);
            ys.push_back(y2);
        }
        sort(ys.begin(), ys.end());
        ys.erase(unique(ys.begin(), ys.end()), ys.end());
        
        Build ( . 1 , 0 , ys.size () - 2 );    // Note: the interval is stored, not the point, so the number of section points less than the number. 1 
        
        Sort (SEG, SEG + * n- 2 , cmp);
        
        double res = 0;
        for (int i = 0; i < 2 * n; ++i) {
            if (i > 0) res += tr[1].len * (seg[i].x - seg[i - 1].x);
            modify ( 1 , find (out [i] .y1), FIND (out [i] .y2) - 1 , out [i] .k);
        }
        
        printf("Test case #%d\n", ++cas);
        printf("Total explored area: %.2lf\n\n", res);
    }
}

 









Guess you like

Origin www.cnblogs.com/mwh123/p/12339804.html