链接:http://poj.org/problem?id=1151
来源:POJ
题意:给出每一个矩形的左上角和右下角,求出这一系列矩形的面积并
//沿垂直方向扫描
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<algorithm>
#define LNode x<<1
#define RNode x<<1|1
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int Max_n=2e2+10;
const int inf=0x3f3f3f3f;
int tag[4*Max_n];
double xbin[Max_n],ybin[Max_n],Min[4*Max_n],cnt[Max_n*4];
struct rect{
double x1,y1,x2,y2;
}r[Max_n];
struct event{
int x1,x2,v;
event(){};
event(double x1,double x2,double v):x1(x1),x2(x2),v(v){};
};
vector<event>G[Max_n];
///区间最小值个数
void update(int x){//区间最小值的个数
if(Min[LNode]==Min[RNode]){
Min[x]=Min[LNode];
cnt[x]=cnt[LNode]+cnt[RNode];
}else if(Min[LNode]<Min[RNode]){
Min[x]=Min[LNode];
cnt[x]=cnt[LNode];
}else{
Min[x]=Min[RNode];
cnt[x]=cnt[RNode];
}
}
void down(int x){//标记下传函数(延迟修改技术)
if(tag[x]!=0){//tag[x]!=0 区间加上某个数
///区间加上某个数
tag[LNode]+=tag[x];
tag[RNode]+=tag[x];
///区间最小值(区间最小值个数)
Min[LNode]+=tag[x];
Min[RNode]+=tag[x];
tag[x]=0;
}
}
//[A,B]:修改为v,[l,r]:当前结点对应的区间,x:当前结点
void change(int A,int B,int v,int l,int r,int x){///区间修改数据(log(n))
if(A<=l&&B>=r) {
///区间加上某个数
tag[x]+=v;
Min[x]+=v;
return ;
}
down(x);//修改之前,检查是否需要下传标记
int mid=(l+r)>>1;
if(A<=mid) change(A,B,v,l,mid,LNode);
if(B>mid) change(A,B,v,mid+1,r,RNode);
///区间最小值个数
update(x);
}
void build(int l,int r,int x){
Min[x]=tag[x]=0;
if(l==r){
cnt[x]=xbin[l]-xbin[l-1];//离散化
return ;
}
int mid=(l+r)>>1;
build(l,mid,LNode);
build(mid+1,r,RNode);
update(x);
}
int main(){
int n,T=0;
while(~scanf("%d",&n)&&n){
for(int i=1;i<=n*4;i++){
tag[i]=0;cnt[i]=0;
Min[i]=0;
}
int xcnt=0,ycnt=0;
for(int i=1;i<=n;i++){
scanf("%lf%lf%lf%lf",&r[i].x1,&r[i].y1,&r[i].x2,&r[i].y2);
xbin[++xcnt]=r[i].x1;xbin[++xcnt]=r[i].x2;
ybin[++ycnt]=r[i].y1;ybin[++ycnt]=r[i].y2;
}
//离散化
sort(xbin+1,xbin+xcnt+1);
sort(ybin+1,ybin+ycnt+1);
xcnt=unique(xbin+1,xbin+xcnt+1)-xbin-1;//去重
ycnt=unique(ybin+1,ybin+ycnt+1)-ybin-1;
for(int i=1;i<=n;i++){
int x1=lower_bound(xbin+1,xbin+xcnt+1,r[i].x1)-xbin;
int x2=lower_bound(xbin+1,xbin+xcnt+1,r[i].x2)-xbin;
int y1=lower_bound(ybin+1,ybin+ycnt+1,r[i].y1)-ybin;
int y2=lower_bound(ybin+1,ybin+ycnt+1,r[i].y2)-ybin;
if(x1<x2){
G[y1].push_back(event(x1+1,x2,1));
G[y2].push_back(event(x1+1,x2,-1));
}
}
xbin[0]=xbin[1];
ybin[0]=ybin[1];
build(1,xcnt,1);
double ans=0;
for(int i=1;i<=ycnt;i++){
double tmp=cnt[1];
if(Min[1]>0) tmp=0;
ans+=(ybin[i]-ybin[i-1])*(xbin[xcnt]-xbin[1]-tmp);
for(int j=0;j<(int)G[i].size();j++)
change(G[i][j].x1,G[i][j].x2,G[i][j].v,1,xcnt,1);
}
for(int i=1;i<=ycnt;i++) G[i].clear();
printf("Test case #%d\n",++T);
printf("Total explored area: %.2f\n\n",ans);
}
return 0;
}