扫描线
Atlantis http://poj.org/problem?id=1151 http://acm.hdu.edu.cn/showproblem.php?pid=1542
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<map> 5 #define mt(a,b) memset(a,b,sizeof(a)) 6 #define lrrt int L,int R,int rt 7 #define iall 1,n,1 8 #define imid int mid=(L+R)>>1 9 #define lson L,mid,rt<<1 10 #define rson mid+1,R,rt<<1|1 11 using namespace std; 12 const int M=210; 13 struct LINE{ 14 struct line{ 15 double left,right,high; 16 int flag; 17 friend bool operator <(line a,line b){ 18 return a.high<b.high; 19 } 20 }l[M]; 21 int cnt; 22 void init(){ 23 cnt=0; 24 } 25 void add(double x1,double x2,double y,int flag){ 26 l[cnt].left=min(x1,x2); 27 l[cnt].right=max(x1,x2); 28 l[cnt].high=y; 29 l[cnt].flag=flag; 30 cnt++; 31 } 32 }g; 33 double x[M]; 34 struct T{ 35 int cover; 36 double len; 37 }tree[M<<2]; 38 void pushup(lrrt){ 39 if(tree[rt].cover) tree[rt].len=x[R-1]-x[L-2]; 40 else if(L==R) tree[rt].len=0; 41 else tree[rt].len=tree[rt<<1].len+tree[rt<<1|1].len; 42 } 43 void update(int x,int y,int val,lrrt){ 44 if(x<=L&&R<=y){ 45 tree[rt].cover+=val; 46 pushup(L,R,rt); 47 return ; 48 } 49 imid; 50 if(mid>=x) update(x,y,val,lson); 51 if(mid<y) update(x,y,val,rson); 52 pushup(L,R,rt); 53 } 54 map<double,int> toid; 55 int main(){ 56 int n,cas=1; 57 while(~scanf("%d",&n),n){ 58 int lx=0; 59 g.init(); 60 while(n--){ 61 double x1,y1,x2,y2; 62 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 63 x[lx++]=x1; 64 x[lx++]=x2; 65 if(y1>y2) swap(y1,y2); 66 g.add(x1,x2,y1,1); 67 g.add(x1,x2,y2,-1); 68 } 69 sort(x,x+lx); 70 n=unique(x,x+lx)-x; 71 toid.clear(); 72 for(int i=0;i<n;i++){ 73 toid[x[i]]=i+1; 74 } 75 mt(tree,0); 76 sort(g.l,g.l+g.cnt); 77 double ans=0; 78 for(int i=0;i<g.cnt-1;i++){ 79 int s=toid[g.l[i].left]; 80 int e=toid[g.l[i].right]; 81 update(s+1,e,g.l[i].flag,iall); 82 ans+=(g.l[i+1].high-g.l[i].high)*tree[1].len; 83 } 84 printf("Test case #%d\nTotal explored area: %.2f\n\n",cas++,ans); 85 } 86 return 0; 87 }
end