hdu1255 线段树+扫描线计算矩形面积交
hdu1255 覆盖的面积
传送门
题意
平面上给出\(n(1\leq n\leq 1000)\)个矩形,每个矩形的左下角坐标为\((x_1,y_1)\),右上角坐标为\((x_2,y_2)\),\(x_1,y_1,x_2,y_2\)均为实数,计算被这些矩形覆盖过至少两次的区域的面积。
题解
线段树+扫描线
在矩形面积并的基础上做出修改
离散化\(x\)坐标,扫描线从下向上扫描
线段树节点维护三个信息:
cnt:区间被覆盖的次数(标记不下传)
s:区间被覆盖至少一次的实际长度
ss:区间被覆盖至少两次的实际长度
#include <bits/stdc++.h>
#define LL long long
#define PII pair<int,int>
#define PLI pair<LL,int>
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define lowbit(x) (x&(-x))
using namespace std;
const int maxn=1010;
int T,n,m,k;
double X[2*maxn];
struct node{
double l,r,h;
int state;
node(){}
node(double l,double r,double h,int state):l(l),r(r),h(h),state(state){}
bool operator < (const node& t)const{
return h<t.h;
}
}nodes[2*maxn];
struct SGT{
int cnt;
double s,ss;
}sgt[8*maxn];
int binary_search(double x){
int l=1,r=k;
while(r>=l){
int mid=(l+r)>>1;
if(X[mid]==x) return mid;
if(X[mid]>x) r=mid-1;
else l=mid+1;
}
return -1;
}
void build(int o,int l,int r){
sgt[o].cnt=sgt[o].s=sgt[o].ss=0;
if(l==r) return;
int mid=(l+r)>>1;
build(lson);
build(rson);
}
void pushup(int o,int l,int r){
if(sgt[o].cnt) sgt[o].s=X[r+1]-X[l];
else if(l==r) sgt[o].s=0;
else sgt[o].s=sgt[o<<1].s+sgt[o<<1|1].s;
if(sgt[o].cnt>1) sgt[o].ss=X[r+1]-X[l];
else if(l==r) sgt[o].ss=0;
else if(sgt[o].cnt==1) sgt[o].ss=sgt[o<<1].s+sgt[o<<1|1].s;
else sgt[o].ss=sgt[o<<1].ss+sgt[o<<1|1].ss;
}
void update(int o,int l,int r,int ql,int qr,int v){
if(ql<=l && r<=qr){
sgt[o].cnt+=v;
pushup(o,l,r);
return;
}
int mid=(l+r)>>1;
if(ql<=mid) update(lson,ql,qr,v);
if(qr>mid) update(rson,ql,qr,v);
pushup(o,l,r);
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
m=1;
for(int i=1;i<=n;i++,m+=2){
double l,r,h1,h2;
scanf("%lf %lf %lf %lf",&l,&h1,&r,&h2);
nodes[m]=node(l,r,h1,1);
nodes[m+1]=node(l,r,h2,-1);
X[m]=l;
X[m+1]=r;
}
m--;
sort(nodes+1,nodes+1+m);
sort(X+1,X+1+m);
k=1;
for(int i=2;i<=m;i++){
if(X[i]!=X[i-1]) X[++k]=X[i];
}
build(1,1,k-1);
double ans=0;
for(int i=1;i<m;i++){
int l=binary_search(nodes[i].l);
int r=binary_search(nodes[i].r)-1;
if(l<=r) update(1,1,k-1,l,r,nodes[i].state);
ans+=sgt[1].ss*(nodes[i+1].h-nodes[i].h);
}
printf("%.2f\n",ans);
}
}