HDU 1828 picture (line segment Tree & scanning line & perimeter)

Source: Internet
Author: User
Picture Time Limit: 6000/2000 MS (Java/others) memory limit: 32768/32768 K (Java/Others)
Total submission (s): 2578 accepted submission (s): 1363


Problem descriptiona Number of rectangular posters, photographs and other pictures of the same shape are pasted on a wall. their sides are all vertical or horizontal. each rectangle can be partially or totally covered by the others. the length of the boundary of the union of all rectangles is called the perimeter.

Write a program to calculate the perimeter. An example with 7 rectangles is shown in Figure 1.



The corresponding boundary is the whole set of line segments drawn in Figure 2.



The vertices of all rectangles have integer coordinates.
Inputyour program is to read from standard input. the first line contains the number of rectangles pasted on the wall. in each of the subsequent lines, one can find the integer coordinates of the lower left vertex and the upper right vertex of each rectangle. the values of those coordinates are given as ordered pairs consisting of an X-coordinate followed by a Y-coordinate.

0 <= number of rectangles <5000
All coordinates are in the range [-keys, 10000] and any existing rectangle has a positive area.

Please process to the end of file.
Outputyour program is to write to standard output. The output must contain a single line with a non-negative integer which corresponds to the perimeter for the input rectangles.
Sample Input
7-15 0 5 10-5 8 20 2515 -4 24 140 -6 16 42 15 10 2230 10 36 2034 0 40 16
 
Sample output
228
 
Sourceioi 1998
Recommendlinle | we have carefully selected several similar problems for you: 1255 1823 3333 1543 question: give you some rectangles parallel to the coordinate axis. Ask you the perimeter of the contour lines of the connected blocks composed of these rectangles. Idea: There are two methods, but the second one is commonly used.
First:
Dividing a rectangle into a horizontal line and a vertical line is exactly the same operation. Let's take a look at how to calculate the horizontal line. The vertical line is just a copy.
Store the horizontal line in a table and sort it by the vertical position (ascending) of the horizontal line. In addition, each horizontal line carries a marking value, and the original rectangle is offline as 1, going online is-1 (corresponding to inserting and deleting a line segment in the past)
From low to high, a part of the X-ray value can be calculated without scanning a X-ray. The calculation method is to calculate the overwrite length of the current total interval, and then find the difference from the overwrite length of the previous total interval (I .e., subtract the absolute value), because each time a line segment is added, if the overwrite length of the total interval is not changed, it indicates that the line segment is actually inside the polygon and is overwritten. It cannot be calculated. As long as the length of the total interval changes, it indicates that this line segment is not covered and not included. It must be calculated.
While the vertical line is the same, the vertical line is saved in a table and sorted by horizontal position (ascending). Each horizontal line carries a marking value, and the left line of the original rectangle is 1, the right line is-1, and then the operation is the same
Second:
The above method seems a bit "stupid". The same job has been done twice. Can you just scan the rectangle once to find the answer, however, we need to improve the information recorded by the line segment Tree node.
The node of each line segment tree must record several pieces of information.
1. l, R. This node represents the coordinates of the left and right endpoints of a line segment.
2. cl, Cr, is a tag with only 0, 1, indicating that the Left and Right endpoints of the node are not covered. There are 1 and 0.
3. CNT, indicating that this interval has been overwritten several times
4. Len, The overwrite length of this interval
5. Num. How many lines are covered by this interval?
It seems that the interval [] is overwritten by [], [], then num = 2
It seems that the interval [] is overwritten by [] [], so num = 1, because they are just connected together
It seems that the interval [] is overwritten by [] [], so num = 1, because it is still a connected segment.
The previous work is the same. Store the horizontal lines in a table, sort them in vertical order, and scan all the horizontal lines from the bottom up. In this method, each time a horizontal line is scanned, can calculate two non-part points, one is a horizontal line, and the other is a vertical line
The method for calculating the horizontal line is the same as the first method, that is, to obtain the absolute value of the difference between the overwrite length of the current total interval and the overwrite length of the previous total interval ], how can we calculate the vertical line? First, we need to know how many vertical lines will exist after this horizontal line is added. The answer is 2 * num. So why should we record num, because the total interval is overwritten by num line segments, so there must be 2 * num endpoints. These endpoints are actually connected to a vertical line. What is the length of these vertical lines?
Is [the height of the next horizontal line-the height of the current horizontal line]. Just multiply the height by 2 * num.
The above is transferred from here. Now the idea is clear. The Code came out smoothly. For details, see the code:
# Include <algorithm> # include <iostream> # include <string. h> # include <stdio. h> using namespace STD; const int INF = 0x3f3f3f3f; const int maxn = 10010; # define lson L, mid, ls # define rson Mid + 1, R, rsint n, m; int cov [maxn <2], num [maxn <2], Len [maxn <2], H [maxn]; // No Initialization is required. The default value is 0 and each time the last line segment is cleared. Bool cl [maxn <2], Cr [maxn <2]; struct node {int x1, x2, H, V; node (int A = 0, int B = 0, int C = 0, int D = 0): x1 (A), X2 (B), H (C), V (d) {}} seg [maxn]; int ABSs (int x) {return x <0? -X: X;} bool CMP (node A, Node B) {return. h <B. h;} void Init () {sort (H, H + M); M = unique (H, H + M)-H;} int Hash (int x) {return lower_bound (H, H + M, x)-H;} void pushup (int l, int R, int RT) {If (COV [RT]) // It indicates that the entire block covers Len [RT] = H [R + 1]-H [L], cl [RT] = cr [RT] = true, num [RT] = 1; else if (L = r) // no more left and right sons. Len [RT] = 0, cl [RT] = cr [RT] = false, num [RT] = 0; else // The entire block is not covered but partially covered {Len [RT] = Len [RT <1] + Len [RT <1 | 1]; cl [RT] = Cl [RT <1], Cr [RT] = cr [RT <1 | 1]; num [RT] = num [RT <1] + num [RT <1 | 1]; if (Cr [RT <1] & cl [RT <1 | 1]) num [RT]-= 1 ;}} void Update (int l, int R, int RT, int L, int R, int d) {If (L <= L & R <= r) {cov [RT] + = D; pushup (L, r, RT); return;} int mid = (L + r)> 1, ls = RT <1, RS = ls | 1; if (L <= mid) update (lson, L, R, D); If (r> mid) Update (RSO N, l, R, D); pushup (L, R, RT);} int main () {int I, PTR, x1, x2, Y1, Y2, ANS, pre; while (~ Scanf ("% d", & N) {for (I = PTR = 0; I <n; I ++) {scanf ("% d", & X1, & Y1, & X2, & Y2); H [PTR] = x1; SEG [PTR ++] = node (x1, x2, Y1, 1); H [PTR] = x2; seg [PTR ++] = node (x1, x2, Y2, -1);} M = PTR, ANS = pre = 0; Init (); sort (SEG, SEG + PTR, CMP); for (I = 0, PTR --; I <PTR; I ++) {Update (0, M-1, 1, hash (SEG [I]. x1), hash (SEG [I]. x2)-1, SEG [I]. v); // M knots of an On-1 line segment ans + = 2 * (SEG [I + 1]. h-seg [I]. h) * num [1] + ABSs (LEN [1]-pre); Pre = Len [1];} Update (0 m-1, 1, hash (SEG [I]. x1), hash (SEG [I]. x2)-1, SEG [I]. v); ans + = ABSs (LEN [1]-pre); printf ("% d \ n", ANS);} return 0 ;}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.