2 10 10 20 20 15 15 25 25.5 0
Test case #1 Total explored area: 180.00
#include <cstdio> #include <algorithm> using namespace std ; double y[300] ; struct Line{ double x , y_up , y_down ; int mark ; }line[300] ; //开始开到110,WA另外三次!!后来看discuss改后就A了! struct Node{ double x ,y_up,y_down ; int cover ; bool isLeaf ; }st[400100]; bool cmp(const Line &a , const Line &b) { return a.x<b.x ; } void build(int l ,int r , int pos) { st[pos].cover = 0 ; st[pos].y_down = y[l] ; st[pos].y_up = y[r] ; st[pos].x = -1 ; st[pos].isLeaf = false ; if(l+1 == r) { st[pos].isLeaf = true ; return ; } int mid = (l+r)>>1 ; build(l,mid,pos<<1); build(mid,r,pos<<1|1) ; } double insert(double x , double y_up , double y_down , int mark , int pos) { if(st[pos].y_down>=y_up || st[pos].y_up<=y_down) { return 0 ; } if(st[pos].isLeaf) { if(st[pos].cover>0) { double temp = st[pos].x ; double area = (x-temp)*(st[pos].y_up-st[pos].y_down) ; st[pos].x = x ; st[pos].cover += mark ; return area ; } else { st[pos].x = x ; st[pos].cover += mark ; return 0 ; } } return insert(x,y_up,y_down,mark,pos<<1)+insert(x,y_up,y_down,mark,pos<<1|1) ; } int main() { int n , c = 1; while(~scanf("%d",&n) && n) { int index = 0 ; for(int i = 0 ; i < n ; ++i) { double x1,y1,x2,y2 ; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2) ; line[index].x = x1 ; line[index].y_down = y1 ; line[index].y_up = y2 ; y[index] = y1 ; line[index++].mark = 1 ; line[index].x = x2 ; line[index].y_down = y1 ; line[index].y_up = y2 ; y[index] = y2 ; line[index++].mark = -1 ; } sort(y,y+index) ; sort(line,line+index,cmp) ; build(0,index-1,1) ; double area = 0.0 ; for(int i = 0 ; i < index ; ++i) { area += insert(line[i].x,line[i].y_up,line[i].y_down,line[i].mark,1) ; } printf("Test case #%d\n",c++) ; printf("Total explored area: %.2lf\n\n",area) ; } return 0 ; }
hdu 1542 Atlantis 线段树求面积并,,,尼玛数据真坑人,数组千万不能开小!
原文地址:http://blog.csdn.net/lionel_d/article/details/44338545