Hdu1828 Picture (line segment tree + discretization + scanning line)

Source: Internet
Author: User

Hdu1828 Picture (line segment tree + discretization + scanning line)

C-Picture Time Limit:2000 MS Memory Limit:10000KB 64bit IO Format:% I64d & % I64uSubmit Status

Description

A 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 cZ operator? Http://www.bkjia.com/kf/ware/vc/ "target =" _ blank "class =" keylink "> memory + CjxjZW50ZXI + pgltzybzcm9" http://www.2cto.com/uploadfile/Collfiles/20140813/20140813085801256.jpg "alt =" \ ">
The vertices of all rectangles have integer coordinates.

Input

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

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 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
Two methods are used to calculate the sum perimeter of n rectangles.

First, traverse the horizontal vertical lines separately, and use the scanning line twice. The first time from left to right, the y coordinate is discretization. After an edge is added, the sum changes. The change amount is the length of the edge, what hasn't changed is to hide it in the original image without forming a new edge. First, sum all vertical edges and calculate the horizontal edges. The final result is the total edges length. You can also avoid finding the interior edges of the image.

#include 
 
  #include 
  
   #include 
   
    #include using namespace std;#define maxn 11000struct node{int l , r ;int sum ;}cl[maxn<<2];struct node1{int k , l , r ;int flag ;}p[maxn] , q[maxn];int lazy[maxn<<2] , x[maxn] , y[maxn] ;bool cmp(node1 a,node1 b){    return a.k < b.k ;}void push_up(int rt){    if( lazy[rt] )        cl[rt].sum = cl[rt].r - cl[rt].l ;    else        cl[rt].sum = cl[rt<<1].sum + cl[rt<<1|1].sum ;}void creat(int rt,int l,int r,int *a){    cl[rt].l = a[l] ;    cl[rt].r = a[r] ;    if( r - l > 1 )    {        creat(rt<<1,l,(l+r)>>1,a);        creat(rt<<1|1,(l+r)>>1,r,a);        push_up(rt);    }    else        cl[rt].sum = 0 ;    return ;}void update(int rt,int l,int r,int flag){    if( cl[rt].l == l && cl[rt].r == r )    {        lazy[rt] += flag ;        push_up(rt);    }    else    {        if( cl[rt<<1].r > l ){                int x = min(cl[rt<<1].r,r) ;            update(rt<<1,l,x,flag);}        if( cl[rt<<1|1].l < r ){                int x = max(cl[rt<<1|1].l,l) ;            update(rt<<1|1,x,r,flag);}        push_up(rt);    }}int main(){int i , j , n , m , x1 , y1 , x2 , y2 , low , ans ;while(scanf("%d", &n)!=EOF){for(i = 0 ; i < n ; i++){scanf("%d %d %d %d", &x1, &y1, &x2, &y2);p[i].k = x1 ;p[i].l = y1 ;p[i].r = y2 ;p[i].flag = 1 ;p[i+n].k = x2 ;p[i+n].l = y1 ;p[i+n].r = y2 ;p[i+n].flag = -1 ;y[i+1] = y1 ;y[i+n+1] = y2 ;q[i].k = y1 ;q[i].l = x1 ;q[i].r = x2 ;q[i].flag = 1 ;q[i+n].k = y2 ;q[i+n].l = x1 ;q[i+n].r = x2 ;q[i+n].flag = -1 ;x[i+1] = x1 ;x[i+n+1] = x2 ;}ans = 0 ;memset(lazy,0,sizeof(lazy));sort(y+1,y+(2*n+1));sort(p,p+2*n,cmp);m = unique(y+1,y+(2*n+1))- (y+1);creat(1,1,m,y);ans = low = 0 ;update(1,p[0].l,p[0].r,p[0].flag);ans += fabs(low-cl[1].sum);low = cl[1].sum ;for(i = 1 ; i < 2*n ; i++)        {            update(1,p[i].l,p[i].r,p[i].flag);            ans += fabs(low - cl[1].sum);            low = cl[1].sum ;        }        sort(q,q+2*n,cmp);        sort(x+1,x+(2*n+1));        m = unique(x+1,x+(2*n+1))-(x+1);        memset(lazy,0,sizeof(lazy));        memset(cl,0,sizeof(cl));        creat(1,1,m,x);        low = 0 ;        update(1,q[0].l,q[0].r,q[0].flag);        ans += fabs(low-cl[1].sum);        low=  cl[1].sum ;        for(i = 1 ; i < 2*n ; i++)        {            update(1,q[i].l,q[i].r,q[i].flag);            ans += fabs( low - cl[1].sum );            low = cl[1].sum ;        }        printf("%d\n", ans);}return 0;}
   
  
 


Second. The first method is troublesome to use two scanning lines. You can also use only one scanning line to separate y coordinates and scan x from left to right to calculate the change value of each sum, in this way, we can obtain the sum of all vertical edges. For horizontal edges, we can use (p [I]. k-p [I-1]. k) * cl [1]. num * 2. the preceding (p [I]. k-p [I-1]. k) The x coordinate difference between two adjacent line segments, cl [1]. num indicates that there are several line segments in the online segment tree. Each line segment increases the horizontal edge of the two endpoints of the line segment. Therefore, you only need to calculate the number of covered edges at that time to obtain the horizontal value-added of that segment.

Count how many line segments are covered at a time. You can use lp and rp to record whether the two endpoints of this node have been overwritten. If the coverage value is 1, then the num in this section is 1, when the two nodes are merged, the num of the parent node is equal to the num Sum of the left and right child nodes. If the rp of the Left node and the lp of the right node are both 1, then the num value of the parent node is less than 1. Finally, the entire line segment is composed of several lines.


#include 
 
  #include 
  
   #include 
   
    #include using namespace std;#define maxn 11000struct node{    int k , l , r , flag ;} p[maxn];struct node1{    int l , r , lp , rp ;    int sum , num ;} cl[maxn<<2];int lazy[maxn<<2] , s[maxn] ;bool cmp(node a,node b){    return a.k < b.k ;}void push_up(int rt){    if( lazy[rt] )    {        cl[rt].lp = cl[rt].rp = 1 ;        cl[rt].num = 1 ;        cl[rt].sum = cl[rt].r - cl[rt].l ;    }    else    {        cl[rt].sum = cl[rt<<1].sum + cl[rt<<1|1].sum ;        cl[rt].num = cl[rt<<1].num + cl[rt<<1|1].num ;        cl[rt].lp = cl[rt<<1].lp ; cl[rt].rp = cl[rt<<1|1].rp ;        if( cl[rt<<1].rp && cl[rt<<1|1].lp )            cl[rt].num-- ;    }}void creat(int rt,int l,int r){    cl[rt].l = s[l] ;    cl[rt].r = s[r] ;    cl[rt].lp = cl[rt].rp = 0 ;    if( r - l > 1 )    {        creat(rt<<1,l,(l+r)/2);        creat(rt<<1|1,(l+r)/2,r);        push_up(rt);    }    else        cl[rt].num = cl[rt].sum = 0 ;}void update(int rt,int l,int r,int flag){    if( cl[rt].l == l && cl[rt].r == r )    {        lazy[rt] += flag ;        push_up(rt);    }    else    {        if( cl[rt<<1].r > l ){                int x = min(r,cl[rt<<1].r) ;            update(rt<<1,l,x,flag);}        if( cl[rt<<1|1].l < r ){                int x = max(l,cl[rt<<1|1].l) ;            update(rt<<1|1,x,r,flag);}        push_up(rt);    }    return ;}int main(){    int n , m , i , j , x1 , y1 , x2 , y2 , ans , low ;    while(scanf("%d", &n)!=EOF)    {        for(i = 0 ; i < n ; i++)        {            scanf("%d %d %d %d", &x1, &y1, &x2, &y2);            p[i].k = x1 ; p[i].l = y1 ; p[i].r = y2 ;p[i].flag = 1 ;            p[i+n].k = x2 ;p[i+n].l = y1 ; p[i+n].r = y2 ; p[i+n].flag = -1 ;            s[i+1] = y1 ;            s[i+n+1] = y2 ;        }        sort(s+1,s+(2*n+1));        sort(p,p+2*n,cmp);        m = unique(s+1,s+(2*n+1))-(s+1) ;        memset(lazy,0,sizeof(lazy));        creat(1,1,m);        ans = 0 ;        low = 0 ;        update(1,p[0].l,p[0].r,p[0].flag);        ans += fabs( low - cl[1].sum );        low = cl[1].sum ;        for(i = 1 ; i < 2*n ; i++)        {            ans += ( p[i].k - p[i-1].k )*cl[1].num*2 ;            update(1,p[i].l,p[i].r,p[i].flag);            ans += fabs( low - cl[1].sum );            low = cl[1].sum ;        }        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.