http://acm.hdu.edu.cn/showproblem.php?pid=1542
题目大意:
求多个正方形面积的并
分析:
用到了线段树的扫描线
先参见大佬的博客吧 讲解随后再写http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html
然后介绍一下去重函数 unique(a,a+n) 返回a去重后的地址 重复元素移动到数组最后不删除 用前先排序
AC代码:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include<list>
#include <bitset>
#include <climits>
#include <algorithm>
#define gcd(a,b) __gcd(a,b)
typedef long long LL;
const LL mod=1e9+7;
const int INF=0x3f3f3f3f;
const int MAX=1e6+5;
const double PI=acos(-1.0);
using namespace std;
struct node{// 存储矩形边的信息
double x1,x2,h;
int flag;// 出边还是入边
}a[MAX];
struct Tree{
int l,r;
double len;// 区间长度
int s; // 出边入边
}T[MAX];
double ls[MAX];// 离散化
bool cmp(node x,node y){
return x.h<y.h;
}
void pushUP(int rt){// 标记上推
if(T[rt].s) T[rt].len=ls[T[rt].r+1]-ls[T[rt].l];
else if (T[rt].l==T[rt].r) T[rt].len=0;
else T[rt].len=T[rt*2].len+T[rt*2+1].len;
}
void build(int rt,int l,int r){// 建树
T[rt].s=0;T[rt].len=0;
T[rt].l=l;T[rt].r=r;
if (l==r) return ;
int mid=(l+r)/2;
build(rt*2,l,mid);
build(rt*2+1,mid+1,r);
}
void update(int rt,int l,int r,int e){// 修改区间
if (T[rt].l>=l&&T[rt].r<=r){
T[rt].s+=e;
pushUP(rt);
return ;
}
int mid=(T[rt].l+T[rt].r)/2;
if (r<=mid) update(rt*2,l,r,e);// 如果在左侧左侧更新
else if (l>mid) update(rt*2+1,l,r,e);// 如果在右侧右侧更新
else{// 两侧都更新
update(rt*2,l,mid,e);
update(rt*2+1,mid+1,r,e);
}
pushUP(rt);
}
int main (){
int cc=1;
int n;
while (scanf ("%d",&n)&&n){
int len=0;
for (int i=0;i<n;i++){
double x1,y1,x2,y2;
scanf ("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
a[len].x1=x1;a[len].x2=x2;a[len].h=y1;
a[len].flag=1;ls[len]=x1;len++;
a[len].x1=x1;a[len].x2=x2;a[len].h=y2;
a[len].flag=-1;ls[len]=x2;len++;
}
sort(ls,ls+len);
sort(a,a+len,cmp);
len=unique(ls,ls+len)-ls;// 去重
build(1,0,len-1);
double ans=0;
for (int i=0;i<2*n;i++){
int l=lower_bound(ls,ls+len,a[i].x1)-ls;
int r=lower_bound(ls,ls+len,a[i].x2)-ls-1;
update(1,l,r,a[i].flag);
ans+=T[1].len*(a[i+1].h-a[i].h);
}
printf("Test case #%d\n",cc++);
printf("Total explored area: %.2f\n\n",ans);
}
}