POJ 1151 离散化线段树+计算几何正矩形求并

我觉得像我这样把所有东西都写的类的ACMer真是一个异类。。。

 

View Code
  1 //Result:wizmann    1151    Accepted    832K    0MS    G++    3310B    
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <string>
  7 #include <cmath>
  8 #include <vector>
  9 #include <set>
 10 #include <map>
 11 #include <iostream>
 12 
 13 using namespace std;
 14 
 15 #define print(x) cout<<x<<endl
 16 #define input(x) cin>>x
 17 #define SIZE 128
 18 
 19 struct node
 20 {
 21     int st,end;
 22     double len;
 23     int cov;
 24 
 25     node(){}
 26     node(int ist,int iend,double ilen)
 27     {
 28         cov=0;
 29         st=ist;end=iend;
 30         len=ilen;
 31     }
 32     
 33     bool equal(int a,int b)
 34     {
 35         return st==a && end==b;
 36     }
 37     
 38     int getmid()
 39     {
 40         return (st+end)>>1;
 41     }
 42     
 43     bool endnode()
 44     {
 45         return end-st<=1;
 46     }
 47 };
 48 
 49 struct point
 50 {
 51     double x,y;
 52     point(){}
 53     point(double i_x,double i_y)
 54     {
 55         x=i_x;y=i_y;
 56     }
 57 };
 58 
 59 struct segment
 60 {
 61     point p1,p2;
 62 
 63     segment(){}
 64     segment(const point& a,const point& b)
 65     {
 66         p1=a;p2=b;
 67     }
 68 };
 69 
 70 struct line
 71 {
 72     double y;
 73     int x1,x2;
 74     int flag;
 75     line(){}
 76     line(int ix1,int ix2,double iy,int iflag)
 77     {
 78         x1=ix1;x2=ix2;
 79         y=iy;flag=iflag;
 80     }
 81     friend bool operator < (const line& a,const line& b)
 82     {
 83         return a.y<b.y;
 84     }
 85 };
 86 
 87 const int ROOT=0;
 88 
 89 
 90 node stree[SIZE<<2];
 91 int n;
 92 map<double,int> hash;
 93 map<int,double> anti_hash;
 94 int sz,ind;
 95 line edge[SIZE<<1];
 96 
 97 
 98 inline int left(int x)
 99 {
100     return (x<<1)+1;
101 }
102 inline int right(int x)
103 {
104     return left(x)+1;
105 }
106 
107 void stree_init(int l,int r,int pos=ROOT)
108 {
109     stree[pos]=node(l,r,anti_hash[r+1]-anti_hash[l]);
110     if(l<r)
111     {
112         int mid=(l+r)>>1;
113         stree_init(l,mid,left(pos));
114         stree_init(mid+1,r,right(pos));
115     }
116 }
117 
118 void update(int l,int r,int cov,int pos=ROOT)
119 {
120     if(stree[pos].equal(l,r))
121     {
122         stree[pos].cov+=cov;
123     }
124     else
125     {
126         int mid=stree[pos].getmid();
127         if(r<=mid) update(l,r,cov,left(pos));
128         else if(l>mid) update(l,r,cov,right(pos));
129         else
130         {
131             update(l,mid,cov,left(pos));
132             update(mid+1,r,cov,right(pos));
133         }
134     }
135 }
136 
137 double query(int pos=ROOT)
138 {
139     double res=0;
140     if(stree[pos].cov>0) res+=stree[pos].len;
141     else if(stree[pos].st!=stree[pos].end)
142     {
143         res+=query(left(pos));
144         res+=query(right(pos));
145     }
146     return res;
147 }
148 
149 int main()
150 {
151     double bx,by,ex,ey;
152     int cas=1;
153     while(input(n) && n)
154     {
155         hash.clear();
156         anti_hash.clear();
157         vector<double> itemx;
158         vector<segment> seg;
159         for(int i=0;i<n;i++)
160         {
161             scanf("%lf%lf%lf%lf",&bx,&by,&ex,&ey);
162             itemx.push_back(bx);
163             itemx.push_back(ex);
164             seg.push_back(segment(point(bx,by),point(ex,by)));
165             seg.push_back(segment(point(bx,ey),point(ex,ey)));
166         }
167         sort(itemx.begin(),itemx.end());
168         sz=itemx.size();
169         ind=0;
170         double ans=0;
171         for(int i=0;i<sz;i++)
172         {
173             if(hash.find(itemx[i])==hash.end())
174             {
175                 //print(itemx[i]<<' '<<ind);
176                 hash[itemx[i]]=ind;
177                 anti_hash[ind]=itemx[i];
178                 ind++;
179             }
180         }
181         sz=seg.size();
182         for(int i=0;i<(int)seg.size();i+=2)
183         {
184             edge[i]=line(hash[seg[i].p1.x],hash[seg[i].p2.x]-1,seg[i].p1.y,1);
185             edge[i+1]=line(hash[seg[i+1].p1.x],hash[seg[i+1].p2.x]-1,seg[i+1].p1.y,-1);
186         }
187         sort(edge,edge+sz);
188         stree_init(0,ind-1);
189         update(edge[0].x1,edge[0].x2,edge[0].flag);
190         for(int i=1;i<sz;i++)
191         {
192             ans+=fabs(edge[i-1].y-edge[i].y)*query();
193             update(edge[i].x1,edge[i].x2,edge[i].flag);
194         }
195         printf("Test case #%d\n",cas++);
196         printf("Total explored area: %.2f\n\n",ans); 
197     }
198     return 0;
199 }

posted on 2012-07-19 23:48  Wizmann  阅读(294)  评论(0)    收藏  举报

导航