您的位置:首页 > 其它

HDU 125 4000 5 覆盖的面积(线段树+面积交)

2017-09-29 20:58 405 查看


http://acm.hdu.edu.cn/showproblem.php?pid=1255

分析:

和求面积并类似     面积并的时候我们只要求出覆盖一次的长度就行    而这里要求出覆盖两次及其以上的长度   分以下情况讨论

1、标记s>=2       覆盖大于等于两次   len1、len2直接求就是了

2、标记s==0      len1、len2都要从左右子区间求解(若为叶子节点   len2为0   覆盖两次是不可能的)

3、标记s==1      len1直接求就是了       若为叶子节点    len2同样为0       如果不是叶子节点    看左右子区间如果有被覆盖过一次的加上这次覆盖   就是两次了

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)
#define FIN	freopen("input.txt","r",stdin)
#define FOUT 	freopen("output.txt","w",stdout)
typedef long long LL;
const LL mod=1e9+7;
const int INF=0x3f3f3f3f;
const int MAX=1e3+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,len2;
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>=2){//               覆盖大于等于两次
T[rt].len=T[rt].len2=ls[T[rt].r+1]-ls[T[rt].l];
}
else if (T[rt].s==1){
T[rt].len=ls[T[rt].r+1]-ls[T[rt].l];
if (T[rt].l==T[rt].r) T[rt].len2=0;
else  T[rt].len2=T[rt*2].len+T[rt*2+1].len;
}
else {
if (T[rt].l==T[rt].r) T[rt].len2=T[rt].len=0;
else{
T[rt].len=T[rt*2].len+T[rt*2+1].len;
T[rt].len2=T[rt*2].len2+T[rt*2+1].len2;
}
}
}
void build(int rt,int l,int r){//     建树
T[rt].s=0;T[rt].len2=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 t;
//FIN;
scanf ("%d",&t);
while (t--){
int len=0,n;
scanf ("%d",&n);
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].len2*(a[i+1].h-a[i].h);
}
printf("%.2f\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息