Atlantis
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 11253 Accepted Submission(s): 4778
The input file is terminated by a line containing a single 0. Don’t process it.
Output a blank line after each test case.
2 10 10 20 20 15 15 25 25.5 0
Test case #1 Total explored area: 180.00题目大意:给出n个矩形(左上角和右下角两个坐标),求总的矩形面积,重复的部分只算一次。思路:线段树+离散化+扫描线。#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=1000005; int mark[maxn<<2]; double sum[maxn<<2],thash[maxn]; struct node { double l,r,h; int cover; node(){} node(double a,double b,double c,int d):l(a),r(b),h(c),cover(d){} bool operator <(const node&x)const { return h<x.h; } }s[maxn<<2]; void updatefather(int pos,int l,int r) { if(mark[pos]) { sum[pos]=thash[r+1]-thash[l]; } else if(l==r)sum[pos]=0;//变成一个点,所以没长度 else sum[pos]=sum[pos<<1]+sum[pos<<1|1]; } void update(int pos,int l,int r,int ql,int qr,int value) { if(ql<=l&&r<=qr) { mark[pos]+=value; updatefather(pos,l,r); return; } int mid=(l+r)>>1; if(ql<=mid)update(pos<<1,l,mid,ql,qr,value); if(qr>mid)update(pos<<1|1,mid+1,r,ql,qr,value); updatefather(pos,l,r); } int main() { int n,cas=1; while(scanf("%d",&n)==1&&n) { memset(mark,0,sizeof(mark)); int m=0,num=2; double x1,x2,y1,y2,ans=0; for(int i=0;i<n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); s[m]=node(x1,x2,y1,1); thash[++m]=x1; s[m]=node(x1,x2,y2,-1); thash[++m]=x2; } printf("Test case #%d\n",cas++); sort(s,s+m); sort(thash+1,thash+1+m); for(int i=2;i<=m;i++)if(thash[i]!=thash[i-1])thash[num++]=thash[i]; for(int i=0;i<m;i++) { int L=lower_bound(thash+1,thash+num,s[i].l)-thash; int R=lower_bound(thash+1,thash+num,s[i].r)-thash-1; if(i)ans+=sum[1]*(s[i].h-s[i-1].h); update(1,1,num-1,L,R,s[i].cover); } printf("Total explored area: %.2lf\n\n",ans); } }
1157



被折叠的 条评论
为什么被折叠?



