Atlantis1542(线段树求矩形覆盖面积)
http://acm.hdu.edu.cn/showproblem.php?pid=1542
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define lson l,mid,i<<1 6 #define rson mid+1,r,i<<1|1 7 using namespace std; 8 const int Ni = 210; 9 int n; 10 struct node { 11 double l,r,h; 12 int s; 13 bool operator < (const node & a) const 14 { 15 return h<a.h; 16 } 17 }arr[Ni*2]; 18 double sum[Ni*3]; 19 int col[Ni*3]; 20 double x[Ni*2]; 21 void pushup(int l,int r,int i) 22 { 23 if(col[i]) sum[i]=x[r+1]-x[l];//这一段被覆盖,一个点代表这个点后面的这一段 24 else if(l==r) sum[i]=0;//没有覆盖的叶子结点 25 else sum[i]=sum[i<<1]+sum[i<<1|1];//不是叶子等于左右儿子之和 26 } 27 void update(double ql,double qr,int s,int l=0,int r=n,int i=1) 28 { 29 if(ql<=x[l]&&x[r]<qr)//[ql,qr)这一段 30 { 31 col[i]+=s; 32 pushup(l,r,i); 33 return; 34 } 35 int mid=(l+r)>>1; 36 if(ql<=x[mid]) update(ql,qr,s,lson); 37 if(qr>x[mid+1]) update(ql,qr,s,rson); 38 pushup(l,r,i); 39 } 40 int main() 41 { 42 int cs=1; 43 while(cin>>n,n) 44 { 45 int m=0; 46 for(int i=0;i<n;i++) 47 { 48 double a,b,c,d; 49 scanf("%lf%lf%lf%lf",&a,&b,&c,&d); 50 x[m]=a; 51 arr[m].l=a;arr[m].r=c;arr[m].h=b;arr[m++].s=1; 52 x[m]=c; 53 arr[m].l=a;arr[m].r=c;arr[m].h=d;arr[m++].s=-1; 54 } 55 sort(x,x+m); 56 sort(arr,arr+m); 57 int q=0; 58 for(int i=1;i<m;i++) 59 { 60 if(x[q]!=x[i]) x[++q]=x[i]; 61 } 62 n=q; 63 memset(col,0,sizeof(col)); 64 memset(sum,0,sizeof(sum)); 65 double ret=0; 66 for(int i=0;i<m-1;i++) 67 { 68 update(arr[i].l,arr[i].r,arr[i].s); 69 ret+=sum[1]*(arr[i+1].h-arr[i].h); 70 } 71 printf("Test case #%d\n",cs++); 72 printf("Total explored area: %.2lf\n\n",ret); 73 } 74 return 0; 75 }