hdu1542 线段树+扫描线 计算矩形面积并
hdu1542 Atlantis
传送门
题意
有\(n(1\leq n\leq 100)\)个矩形,每个矩形的左下角坐标为\((x_1,y_1)\),右上角坐标为\((x_2,y_2)\),其中\(0\leq x_1<x_2 \leq 100000, 0\leq y_1<y_2 \leq 100000\),坐标为实数,计算所有矩形面积并。
题解
线段树+扫描线
从下向上扫描,每个矩形分为上位边和下位边,拥有的信息为:
l:左端点\(x\)坐标
r:右端点\(x\)坐标
h:\(y\)坐标
d:上位边还是下位边
线段树中维护两个变量:
\(cnt\):当前节点维护的区间被覆盖的次数,\(cnt=-1\)表示当前节点的左儿子和右儿子的\(cnt\)不一致
\(sum\):当前节点维护的区间中\(cnt\)不为\(0\)的实际区间的总长度
将\(x\)坐标离散化,线段树维护,离散化数组为\(X\),线段树中的节点\(l\)表示\([X[l],X[l+1]]\)这段区间被覆盖的次数
#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=110;
int n,cas,k;
double X[2*maxn];
struct node{
double l,r,h;// l表示x左端点,r表示x右端点,h表示y坐标
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 sum;
}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 pushup(int o){
if(sgt[o<<1].cnt==-1 || sgt[o<<1|1].cnt==-1){
sgt[o].cnt=-1;
}
else if(sgt[o<<1].cnt!=sgt[o<<1|1].cnt){
sgt[o].cnt=-1;
}
else{
sgt[o].cnt=sgt[o<<1].cnt;
}
sgt[o].sum=sgt[o<<1].sum+sgt[o<<1|1].sum;
}
void pushdown(int o,int l,int r){
int mid=(l+r)>>1;
if(sgt[o].cnt!=-1){
sgt[o<<1].cnt=sgt[o<<1|1].cnt=sgt[o].cnt;
sgt[o<<1].sum=(sgt[o<<1].cnt?X[mid+1]-X[l]:0);
sgt[o<<1|1].sum=(sgt[o<<1|1].cnt?X[r+1]-X[mid+1]:0);
}
}
void build(int o,int l,int r){
if(l==r){
sgt[o].cnt=0;
sgt[o].sum=0.0;
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(o);
}
void update(int o,int l,int r,int ql,int qr,int state){
if(ql<=l && r<=qr){
if(sgt[o].cnt!=-1){
sgt[o].cnt+=state;
sgt[o].sum=(sgt[o].cnt?X[r+1]-X[l]:0);
return;
}
}
pushdown(o,l,r);
int mid=(l+r)>>1;
if(ql<=mid) update(lson,ql,qr,state);
if(qr>mid) update(rson,ql,qr,state);
pushup(o);
}
int main(){
while(scanf("%d",&n)!=EOF && n){
printf("Test case #%d\n",++cas);
int m=0;
for(int i=1;i<=n;i++){
double l,r,h1,h2;
scanf("%lf %lf %lf %lf",&l,&h1,&r,&h2);
nodes[++m]=node(l,r,h1,1);
X[m]=l;
nodes[++m]=node(l,r,h2,-1);
X[m]=r;
}
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];
}
sort(nodes+1,nodes+1+m);
build(1,1,k-1);
double ans=0.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].sum*(nodes[i+1].h-nodes[i].h);
}
printf("Total explored area: %.2f\n\n",ans);
}
}

浙公网安备 33010602011771号