poj-1177 Picture (Rectangle perimeter and Segment tree + scan line)

Source: Internet
Author: User

Topic Link: Click to open the link

Picture
Time Limit: 2000MS Memory Limit: 10000K
Total Submissions: 11706 Accepted: 6175

Description

A number of rectangular posters, photographs and other pictures of the same shape is pasted on a wall. Their sides is all vertical or horizontal. Each rectangle can is 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 are shown in Figure 1.

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

The vertices of all rectangles has an integer coordinates.

Input

Your program was to read from standard input. The first line contains the number of rectangles pasted on the wall. In 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 is given as ordered pairs consisting of an x-coordinate followed by a y-coordinate.

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

Output

Your 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 Rectang Les.

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

Test instructions: There are many rectangles on the plane, and the rectangles will cover each other, asking the total perimeter.

Idea: See this problem to think of the rectangular area before done and, this problem than the problem to deal with a cross-side, except that it is the same ~ saw click to open the link to the idea of the great God after the enlightened.

In the previous rectangular area and the template changed the AC, the code of the specific comments, see the Code bar.

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm>using namespace    STD; #define N 10010struct node{int l,r;    int RL,RR;    int c;///The weight of the segment, The edge is 1, the Out Edge is-1 int cnt;///the vertical effective length int part;///in the vertical direction valid segment has several intervals, the successive two intervals calculates one.    int isl,isr;///whether the left and right endpoints of the interval are overwritten}tree[n<<2];struct line{int x;    int y1,y2; int C;} Line[n<<1];int Y[n];bool cmp (line A,line b) {if (a.x==b.x) return a.c>b.c;///note whether POJ or HDU this step does not add to the AC, but The code is wrong, because the heavy edges cannot be judged.    If there is a heavy edge, the first judgment of the edge can be resolved. return a.x<b.x;}    void build (int root,int l,int r) {tree[root].l=l;    Tree[root].r=r;    TREE[ROOT].RL=Y[L];    TREE[ROOT].RR=Y[R];    tree[root].c=0;    tree[root].cnt=0;    tree[root].part=0;    tree[root].isl=tree[root].isr=0;    if (l+1==r) return;    int m= (L+R) >>1;    Build (ROOT&LT;&LT;1,L,M); Build (Root<<1|1,m,r);}            void pushup (int root) {if (tree[root].c>0) {tree[root].cnt=tree[root].rr-tree[root].rl; TreE[root].isl=tree[root].isr=1;    Tree[root].part=1;            } else {if (TREE[ROOT].L+1==TREE[ROOT].R) {tree[root].cnt=0;            tree[root].isl=tree[root].isr=0;        tree[root].part=0;            } else {tree[root].cnt=tree[root<<1].cnt+tree[root<<1|1].cnt;            tree[root].isl=tree[root<<1].isl;            tree[root].isr=tree[root<<1|1].isr; Tree[root].part=tree[root<<1].part+tree[root<<1|1].part-tree[root<<1].isr*tree[root<<1        |1].ISL; }}}void Update (int root,line a) {if (tree[root].rl==a.y1&&tree[root].rr==a.y2) {TREE[ROOT].C+=A.C        ;        Pushup (root);    Return    } if (A.Y2&LT;=TREE[ROOT&LT;&LT;1].RR) {update (ROOT&LT;&LT;1,A);    } else if (A.Y1&GT;=TREE[ROOT&LT;&LT;1|1].RL) {update (ROOT&LT;&LT;1|1,A);        } else {line temp=a;        temp.y2=tree[root<<1].rr; UpdateROOT&LT;&LT;1,TEMP);        Temp=a;        temp.y1=tree[root<<1|1].rl;    Update (ROOT&LT;&LT;1|1,TEMP); } pushup (root);}    int main () {int x1,y1,x2,y2;    int n;    int flag=0;        while (~SCANF ("%d", &n)} {if (flag==1) break;        int t=1;            for (int i=0;i<n;i++) {scanf ("%d%d%d%d", &x1,&y1,&x2,&y2);            line[t].x=x1;            Line[t].y1=y1;            Line[t].y2=y2;            Line[t].c=1;            Y[t++]=y1;            line[t].x=x2;            Line[t].y1=y1;            Line[t].y2=y2;            Line[t].c=-1;        Y[t++]=y2;        }///save each edge and each Y value of sort (line+1,line+t,cmp);        Sort (y+1,y+t);        int num=2;        for (int i=2;i<t;i++) if (y[i]!=y[i-1]) y[num++]=y[i];///de-build (1,1,NUM-1);        Update (1,line[1]);        int sum=tree[1].cnt;        int Last_part=tree[1].part; int last_cnt=tree[1].cnt;///preprocessing the first edge, because it needs to be updated before processing for (iNT i=2;i<t;i++) {update (1,line[i]); Sum+=abs (TREE[1].CNT-LAST_CNT)////////////////When a new line segment is entered, the length of the "not internal edge" is calculated by subtracting the effective length of the update from the effective length before the update, and the area and the rectangular area are the opposite, and need exactly the length of the inner edge s um+=2*last_part* (line[i].x-line[i-1].x), or///To find a cross, a section (interval) has two sides. Note It should be easy to understand that you want to use the part value before updating.            The number of bars on the side is seen from the left side, that is, we can ensure that only the previous x to the current x before the distance has the number of paragraphs before the update side length Last_part=tree[1].part;    last_cnt=tree[1].cnt;///scrolling} printf ("%d\n", sum); } return 0;}


poj-1177 Picture (Rectangle perimeter and Segment tree + scan line)

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.