主要作为代码参考
http://acm.hdu.edu.cn/showproblem.php?pid=1542
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
const int M=2222;
double X[M];//离散化
struct node{
double l,r,h;//因为有小数,所以我们存边的时候要存为小数
int d;//存上边还是下边
}nodes[M];
struct t{//线段树
int cnt;//线段树存下边数-上边数,如果子节点下边数-上边数不同我们直接赋值-1
double sum;//区间长度
}tr[M*4];
bool cmp(node a,node b){
return a.h<b.h;
}
void pushup(int i){//上推
if(tr[i*2].cnt==-1||tr[i*2+1].cnt==-1){
tr[i].cnt=-1;
}else if (tr[i*2].cnt!=tr[i*2+1].cnt){
tr[i].cnt=-1;
}else
tr[i].cnt=tr[i*2].cnt;
tr[i].sum=tr[i*2].sum+tr[i*2+1].sum;
}
void pushdown(int i,int l,int r){
int mid=(r+l)/2;
if(tr[i].cnt!=-1){
tr[i*2].cnt=tr[i*2+1].cnt=tr[i].cnt;
if(tr[i].cnt==0){
tr[i*2].sum=tr[i*2+1].sum=0;
}else{
tr[i*2].sum=X[mid+1]-X[l];
tr[i*2+1].sum=X[r+1]-X[mid+1];
}
}
}
void build(int i,int l,int r){//建线段树
if(l==r){//叶子结点
tr[i].sum=0;
tr[i].cnt=0;
return;
}
int mid =(r+l)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
pushup(i);
}
void update(int i,int l,int r,int x,int y,int d){
if(x<=l&&y>=r){
if(tr[i].cnt!=-1){
tr[i].cnt+=d;
tr[i].sum=(tr[i].cnt?(X[r+1]-X[l]):0);
return;
}
}
pushdown(i,l,r);
int mid=(r+l)/2;
if(x<=mid)
update(i*2,l,mid,x,y,d);
if(y>mid)
update(i*2+1,mid+1,r,x,y,d);
pushup(i);
}
int bin(double k,int n,double d[]){
int l=1,r=n;
while(l<=r){
int mid=(r+l)/2;
if(d[mid]<k){
l=mid+1;
}else if(d[mid]==k)
return mid;
else{
r=mid-1;
}
}
return -1;
}
int main(){
int q;
int kase=0;
while(~scanf("%d",&q)&&q){
int n=0,m=0;
for(int i=1;i<=q;i++){
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
X[++n]=x1;//存边
nodes[++m].l=x1;
nodes[m].r=x2;
nodes[m].h=y1;
nodes[m].d=1;
X[++n]=x2;
nodes[++m].l=x1;
nodes[m].r=x2;
nodes[m].h=y2;
nodes[m].d=-1;
}
sort(X+1,X+1+n);
sort(nodes+1,nodes+1+m,cmp);//排序
int k=1;
for(int i=2;i<=n;i++){
if(X[i-1]!=X[i])
X[++k]=X[i];//离散化
}
build(1,1,k-1);//在x轴上一共有k-1段
double ret=0.0;
for(int i=1;i<m;i++){
int x,y;
x=bin(nodes[i].l,k,X);
y=bin(nodes[i].r,k,X)-1;
if(x<=y)
update(1,1,k-1,x,y,nodes[i].d);
ret+=tr[1].sum*(nodes[i+1].h-nodes[i].h);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",++kase,ret);
}
return 0;
}