1. 程式人生 > >[codevs3044]矩形面積求並

[codevs3044]矩形面積求並

small inpu pac per 右上角 define bsp update segment

題目描述 Description
輸入n個矩形,求他們總共占地面積(也就是求一下面積的並)
輸入描述 Input Description

可能有多組數據,讀到n=0為止(不超過15組)

每組數據第一行一個數n,表示矩形個數(n<=100)

接下來n行每行4個實數x1,y1,x2,y1(0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000),表示矩形的左下角坐標和右上角坐標

輸出描述 Output Description
每組數據輸出一行表示答案
樣例輸入 Sample Input
2
10 10 20 20
15 15 25 25.5
0
樣例輸出 Sample Output
180.00
數據範圍及提示 Data Size & Hint

矩形面積並,掃描線+線段樹

本題的線段樹比較奇怪
其中的坑點在pushup,線段樹維護的區間[l,r]如果l,r相等並不是一段空集,而是線段pos[l]-pos[r+1] 這一線段

技術分享
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include
<cmath> #include<cstring> using namespace std; typedef long long LL; typedef pair<int,int> PII; #define mem(a,b) memset(a,b,sizeof(a)) inline int read() { int x=0,f=1;char c=getchar(); while(!isdigit(c)){if(c==-)f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-0;c=getchar();}
return x*f; } const int maxn=210; int n,add[maxn<<2]; double a,b,c,d,pos[maxn],sum[maxn<<2],ans; struct segment { double X,x,Y;int tag; segment(){} segment(double _1,double _2,double _3,int _4):X(_1),x(_2),Y(_3),tag(_4) {} bool operator < (const segment &s)const {return Y<s.Y;} }seg[maxn]; void pushup(int l,int r,int o) { if(add[o])sum[o]=pos[r+1]-pos[l]; else if(l==r)sum[o]=0; else sum[o]=sum[o<<1]+sum[o<<1|1]; } void update(int l,int r,int o,int L,int R,int c) { if(L==l && r==R) { add[o]+=c; pushup(l,r,o); return; } int mid=(l+r)>>1,lo=o<<1,ro=lo|1; if(R<=mid)update(l,mid,lo,L,R,c); else if(L>mid)update(mid+1,r,ro,L,R,c); else update(l,mid,lo,L,mid,c),update(mid+1,r,ro,mid+1,R,c); pushup(l,r,o); } int main() { while(scanf("%d",&n)!=EOF && n) { mem(pos,0);mem(sum,0);mem(add,0);ans=0; for(int i=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&a,&b,&c,&d); seg[i*2]=segment(a,c,b,1);pos[i*2]=a; seg[i*2-1]=segment(a,c,d,-1);pos[i*2-1]=c; } sort(seg+1,seg+n*2+1);sort(pos+1,pos+n*2+1); for(int i=1;i<=2*n;i++) { int l=lower_bound(pos+1,pos+n*2+1,seg[i].X)-pos; int r=lower_bound(pos+1,pos+n*2+1,seg[i].x)-pos-1; update(1,2*n,1,l,r,seg[i].tag); ans+=sum[1]*(seg[i+1].Y-seg[i].Y); } printf("%.2lf\n",ans); } return 0; }
View Code

[codevs3044]矩形面積求並