这道题在区间并的基础上稍微修改了一下,多了一个记录覆盖两次或两次以上的长度变量 ss 和 判断条件
详细讲解 Titanium
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls rt<<1
#define rs rt<<1|1
#define mid(rt) (p[rt].l+p[rt].r)>>1
using namespace std;
const int maxn=10010;
struct edge
{
double l,r,h;
int v;
}e[maxn<<2];
bool cmp(edge a,edge b)
{
return a.h<b.h;
}
double x[maxn<<2];
struct node
{
int l,r;
int cnt; //该节点被覆盖的情况
double s; //覆盖一次的长度
double ss; //覆盖两次或两次以上的长度
}p[maxn<<2];
void build(int l,int r,int rt)
{
p[rt].cnt = 0;
p[rt].s = p[rt].ss = 0;
p[rt].l = l , p[rt].r = r;
if(l==r)
return ;
int m = mid(rt);
build(l,m,ls);
build(m+1,r,rs);
}
void pushup(int rt)
{
if(p[rt].cnt) //非零,已经被整段覆盖
p[rt].s = x[p[rt].r+1]-x[p[rt].l]; //利用[ , ),这个区间性质,左闭右开
else if(p[rt].l==p[rt].r) //这是一个点而不是线段
p[rt].s = 0;
else //是一条没有整个区间被覆盖的线段,合并左右子的信息
p[rt].s = p[ls].s + p[rs].s;
if(p[rt].cnt>1) //区间被覆盖2次或2次以上
p[rt].ss = x[p[rt].r+1]-x[p[rt].l];
else if(p[rt].l==p[rt].r) //叶子结点
p[rt].ss = 0;
else if(p[rt].cnt==1) //被完全覆盖1次(不确定有无覆盖两次或两次以上的部分)
p[rt].ss = p[ls].s+p[rs].s;
else //不完全不知道被覆盖的情况(不知道有没有被覆盖,被覆盖了几次,长度是多少都不知道)
p[rt].ss = p[ls].ss+p[rs].ss;
}
void update(int l,int r,int rt,int f)
{
if(p[rt].l==l && p[rt].r==r)
{
p[rt].cnt += f;
pushup(rt);
return ;
}
int m = mid(rt);
if(r<=m)
update(l,r,ls,f);
else if(l>m)
update(l,r,rs,f);
else
{
update(l,m,ls,f);
update(m+1,r,rs,f);
}
pushup(rt);
}
int main()
{
int t,n;
double x1,y1,x2,y2;
scanf("%d",&t);
while(t--)
{
int tot=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
e[tot].l = e[tot+1].l = x[tot] = x1;
e[tot].r = e[tot+1].r = x[tot+1] = x2;
e[tot].h = y1;
e[tot+1].h = y2;
e[tot].v = 1;
e[tot+1].v = -1;
tot += 2;
}
sort(e,e+tot,cmp);
sort(x,x+tot);
int k = unique(x,x+tot)-x;
build(0,k-1,1);
double ans=0;
for(int i=0;i<tot;i++)
{
int l=lower_bound(x,x+k,e[i].l)-x;
int r=lower_bound(x,x+k,e[i].r)-x-1;
update(l,r,1,e[i].v);
ans += (e[i+1].h-e[i].h)*p[1].ss;
}
printf("%.2lf\n",ans);
}
return 0;
}
本文深入解析HDU-1255覆盖面积问题,介绍了一种基于区间并集算法的解决方案,通过构建线段树来高效计算线段覆盖的总长度及两次以上覆盖的长度,适用于解决计算机科学中复杂的区间覆盖问题。

371

被折叠的 条评论
为什么被折叠?



