hdu Atlantis (segment tree and the area)

Problem 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
***************************************************************************************************************************
Segment tree area and, most importantly, the understanding of scan lines, according to the x or y coordinate construction scan line, the bobbin thread is added, the line removal (i.e., the edge and the edge), every addition or deletion of a segment, to calculate the area.
Thereby to the x-coordinate (y-coordinate) when computing deduplication, but also sort the x coordinate
Specific understand:

As the name suggests, the scanning method is rectangular with a sweep of all imaginary line in the process of writing code, this line is very important. Direction, it can sweep around, may sweep down. The method is the same, here I use bottom-up scanning.

     

Shown, there are two rectangles within a coordinate system as in FIG. It is given by the position coordinates of the top right and bottom left vertex. Vertical scanning is based on the x-axis segment tree, y rectangle two parallel sides is of no use, directly remove here. As shown below.

Now imagine a line sequential scanning start up from the bottom side. Segment tree is used to maintain current coverage in the x-axis segment of the total length, total length is initially zero. Ret to save the total area of ​​a rectangle, initially zero.

Up by the scan, to scan a rectangular base segment tree is inserted into it, when the bottom edge of the scan line is deleted from the tree to the top of the rectangle. The method is implemented in the code, each edge has a flag variable, a bottom edge, top edge -1.

Cover with an array (maintained by the segment tree) to indicate whether there is an edge within the coverage range x coordinate, initially all zero. Insert or delete operation directly cover [] + = flag. When the cover []> 0, the edge section must be covered.

To start scanning the first line, it will be pressed into the segment tree, in this case covering the overall length L of the line segment 10 is the x-axis. Calculate it to be scanned at a distance from the edge of S (i.e., the difference between the ordinate of the line segments, in this case 3 in this example).

                                                                               The ret + = L * S. (example in increments of 10 * 3 = 30)

The results shown below

  Orange area indicates the area that has been calculated.

Scan to the second edge, pressed into the segment tree is calculated at this time covered on the x axis side of the total length.

Examples in this case L = 15. And a lower side to be scanned distance S = 2. ret + = 30. As shown below.

Green area for the second time increment area.

Then scan the top side of the lower rectangle, the rectangle is deleted from the bottom edge of the segment tree, and calculates the next increment area. As shown below.

 Blue area increments area.

At this time, the total area of ​​the rectangular footprint has been calculated completed. Can be seen that, when a total of n base and a top edge, only scan from the bottom up to the n-1 side calculates the total area.

(Reference to God blog)

***************************************************************************************************************************

  . 1 #include <cstdio>
   2 #include <CString>
   . 3 #include <algorithm>
   . 4  the using  namespace STD;
   . 5  #define INF 0x3f3f3f3
   . 6  #define MAX 110
   . 7  #define L (RT) RT <<. 1
   . 8  #define R & lt (RT ) RT << 1 | 1
   . 9  
10  struct segment // save the rectangular upper and lower boundaries 
. 11  {
 12 is    Double L, R & lt, H; // left abscissa, ordinate 
13 is    int F; // -1 for the lower bound, the upper 1 boundary 
14 } SS [ 2 *MAX];
 15  struct Node // segment tree node 
16  {
 . 17    int L, R & lt;
 18 is    int CNT; // where the node is covered 
. 19    Double len; // total length of the covered section 
20 is    int MID ()
 21 is    { return (L + R & lt) >> . 1 ;}
 22 is } Tree [ 2 * * MAX . 4 ];
 23 is  Double POS [MAX << 2 ];
 24  int the nums;
 25  
26 is  int CMP (segment A, segment B)
 27 {
 28   return a.h<b.h;
 29 }
 30 
 31 void build(int a, int b ,int rt)
 32 {
 33  tree[rt].l=a; tree[rt].r=b; tree[rt].cnt=0; tree[rt].len=0;
 34  if(a==b) return ;
 35  int mid=tree[rt].mid();
 36  build(a,mid,L(rt));
 37  build(mid+1,b,R(rt));
 38 }
 39 
 40 int binary(double key ,int low, int high)
 41 {
 42    while(low<=high)
 43    {
 44       int mid=(low+high)>>1;
 45       if(pos[mid] == key) return mid;
 46       else if(key < pos[mid]) high=mid-1;
 47       else                    low=mid+1;
 48    }
 49    return -1;
 50 }
 51 
 52 void get_len ( int RT)
 53 is  {
 54 is     IF (Tree [RT] .cnt) // non-zero, has been covered the whole 
55        Tree [RT] = .LEN POS [Tree [RT] .r + . 1 ] - POS [Tree [RT] .L];
 56 is     the else  IF (Tree [RT] .L == Tree [RT] .r) // not the line segment 
57 is        Tree [RT] .LEN = 0 ;
 58     the else  // is but one segment and no cover the whole, it can be obtained from information about the child's 
59        Tree [RT] Tree .LEN = [L (RT)] + len. Tree [R & lt (RT)] len;.
 60  }
 61 is  
62 is  void UPDATA ( int A,int B, int Val, int RT)
 63 is  {
 64     IF (Tree [RT] .L && == A Tree [RT] .r == B) // target section 
65     {
 66        Tree [RT] + = Val .cnt ; // update interval is covered in this case 
67        get_len (RT);   // updates the total length of this interval is covered by the 
68        return ;
 69     }
 70     int MID = Tree [RT] .mid ();
 71 is     IF (B <= MID) // only access the left child 
72        UPDATA (A, B, Val, L (RT));
 73 is     the else  IF (A> MID) //Children have access only 
74        UPDATA (A, B, Val, R & lt (RT));
 75     the else  // about to be accessed 
76     {
 77        UPDATA (A, MID, Val, L (RT));
 78        UPDATA (MID + . 1 , B, Val, R & lt (RT));
 79     }
 80     get_len (RT); // calculate the total length of the covered section 
81  }
 82  
83  int main ()
 84  {
 85    int Case = 0 ;
 86    int n-;
 87    the while (Scanf ( " % D " , & n-)! && the EOF = n-)
 88   {
 89     nums=0;
 90     for(int i=0; i<n; i++)
 91     {
 92       double x1,y1,x2,y2;
 93       scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
 94       ss[nums].l=x1;  ss[nums].r=x2; ss[nums].h=y1; ss[nums].f=1;
 95       //记录上边界的信息
 96       ss[nums+1].l=x1; ss[nums+1].r=x2; ss[nums+1].h=y2; ss[nums+1].f=-1 ;
 97        // record boundary information 
98        POS [the nums] = X1; POS [the nums + 1 ] = X2;
 99        // record the abscissa 
100        the nums = + 2 ;
 101  
102      }
 103  
104      Sort (SS, SS + the nums , CMP); // horizontal sorted in ascending ordinate 
105      Sort (POS, POS + the nums); // abscissa ascending order of
 106      // for (int I = 0; I <the nums; I ++) the printf ( "%. %% .2lf .2lf 2Lf \ n-", SS [I] .L, SS [I] .r, SS [I] .h); 
107      int m = . 1 ;
 108      for ( int I = . 1; I <the nums; I ++ )
 109        IF ! (POS [I] POS = [I- . 1 ]) // deduplication 
110          POS [++ m] = POS [I];
 111  
112      Build ( 0 , M- . 1 , . 1 ) ;   // interval is discretized [0, m-1], this contribution 
113      Double ANS = 0 ;
 114      for ( int I = 0 ; I <the nums; I ++) // out of each horizontal line and updating 
115      {
 1 16         int L = binary (SS [I] .L, 0 , M- . 1 );
 117         int r=binary(ss[i].r,0,m-1)-1;
118        updata(l,r,ss[i].f,1); //用这条线段去更新
119        ans += (ss[i+1].h-ss[i].h)*tree[1].len;
120        //printf("%.2lf\n",ans);
121     }
122     printf("Test case #%d\n",++Case);
123     printf("Total explored area: %.2f\n\n",ans);
124   }
125   return 0;
126 }
View Code

 

Reproduced in: https: //www.cnblogs.com/sdau--codeants/p/3531305.html

Guess you like

Origin blog.csdn.net/weixin_33819479/article/details/93432881
Recommended