一开始为了节省时间设了-1.
遇到0就不往下搜,结果没想清楚,各种bug.
基本思路就是离散化x的小数(详细点的说明在这里).
用平行x轴的扫描线扫描整个区域.
每次扫描把已经染色的长度算(endis[r]-endis[l])出来,乘以这次于上一次y的差就是本次的差.
还有就是区间的连续,也就是为什么是(endis[r]-endis[l]),这里用的是叶节点为[1,2][[2,3]...这种划分.就避免了需要判断是否区间连续.
/********************** hash x scan line on y **********************/ #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <set> #define lson num<<1 #define rson num<<1|1 #define gl l,(l+r)>>1,lson #define gr (l+r)>>1,r,rson using namespace std; const int maxn = 100005; struct ord ///save order { double y,x[2]; int flag; }o[210]; bool ord_cmp (ord a,ord b) {return a.y<b.y;} int st[500<<3]; void push_down(int num) ///push_down without hesitates { st[lson]+=st[num]; st[rson]+=st[num]; st[num]=0; } void push_up(int num) ///push_up without hesitates { int v=min(st[lson],st[rson]); st[num]+=v; st[lson]-=v; st[rson]-=v; } void updata(int a,int b,int v,int l,int r,int num) { if(a<=l&&r<=b) { st[num]+=v; push_up(num); return; } if(l+1==r) return; push_down(num); updata(a,b,v,gl); updata(a,b,v,gr); push_up(num); } map<double,int> dis; ///discrete map<int,double>endis; ///continuous set<double>buf; ///buffer for dis double calc(int l,int r,int num) { if(st[num]) return endis[r]-endis[l]; if(l+1==r) return 0; push_down(num); return calc(gl)+calc(gr); } int main() { #ifndef ONLINE_JUDGE freopen("poj1151.in","r",stdin); #endif // ONLINE_JUDGE int n,cas=1; while(~scanf("%d",&n)&&n) { buf.clear(); dis.clear(); endis.clear(); for(int i=0;i<n;i++) { double a,b,c,d; scanf("%lf%lf%lf%lf",&a,&b,&c,&d); buf.insert(a); buf.insert(c); o[i*2+1].x[0]=o[i*2].x[0]=min(a,c); o[i*2+1].x[1]=o[i*2].x[1]=max(a,c); o[i*2].y=min(b,d); o[i*2+1].y=max(b,d); o[i*2].flag=1; o[i*2+1].flag=-1; } sort(o,o+n*2,ord_cmp); int cnt=1; for(set<double>::iterator i=buf.begin(),end=buf.end();i!=end;i++,cnt++) { pair<double,int>tmp1(*i,cnt); pair<int,double>tmp2(cnt,*i); dis.insert(tmp1); endis.insert(tmp2); } n*=2; int m=buf.size(); double ans=0,last=o[0].y; for(int i=0;i<n;i++) { int a=dis[o[i].x[0]],b=dis[o[i].x[1]]; if(last!=o[i].y) { ans+=calc(1,m,1)*(o[i].y-o[i-1].y); last = o[i].y; } updata(a,b,o[i].flag,1,m,1); } printf("Test case #%d\nTotal explored area: %.2f\n\n",cas++,ans); } return 0; }