您的位置:首页 > 其它

HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)

2014-08-09 16:50 309 查看
题目链接

题意:中文题意。

分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt》=0改成cnt>=2就行了,、

但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了,因为虽然现在都不等于

2,但是之前的那个线段加上现在的已经覆盖2次了。

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL __int64
#define lson l, mid, 2*rt
#define rson mid+1, r, 2*rt+1
const int maxn = 2000+10;
using namespace std;
int n;
double y[maxn];
struct node
{
int l, r, c;
double cnt, lf, rf, more; //cnt还是代表覆盖的长度,增加了more代表两次及以上覆盖的长度
}tr[4*maxn];
struct Line
{
double x, y1, y2;
int f;
}line[maxn];
bool cmp(Line a, Line b)
{
return a.x < b.x;
}
void build(int l, int r, int rt)
{
tr[rt].l = l; tr[rt].r = r;
tr[rt].c = 0;  tr[rt].cnt = 0;
tr[rt].more = 0;
tr[rt].rf = y[r];  tr[rt].lf = y[l];
if(l+1==r) return;
int mid = (l+r)/2;
build(l, mid, 2*rt);
build(mid, r, 2*rt+1);
}
void calen(int rt)
{
if(tr[rt].c==0)
{
if(tr[rt].l+1==tr[rt].r)
{
tr[rt].cnt = 0; tr[rt].more = 0;
}
else
{
tr[rt].cnt = tr[2*rt].cnt+tr[2*rt+1].cnt;
tr[rt].more = tr[2*rt].more+tr[2*rt+1].more;
}
}
if(tr[rt].c==1)  //注意这一步是关键
{
tr[rt].cnt = tr[rt].rf-tr[rt].lf;
if(tr[rt].l+1==tr[rt].r)  //因为没有注意是否到最后,错了一遍
tr[rt].more = 0;
else
tr[rt].more = tr[2*rt].cnt + tr[2*rt+1].cnt; //为1的时候如果下面也有就加上
}
if(tr[rt].c>=2)
{
tr[rt].more = tr[rt].rf-tr[rt].lf;
tr[rt].cnt = tr[rt].more;
}
}
void update(int rt, Line e)
{
if(e.y1==tr[rt].lf && e.y2==tr[rt].rf)
{
tr[rt].c += e.f;
calen(rt);
return;
}
if(e.y2<=tr[2*rt].rf) update(2*rt, e);
else if(e.y1>=tr[2*rt+1].lf) update(2*rt+1, e);
else
{
Line tmp;
tmp = e;
tmp.y2 = tr[2*rt].rf; update(2*rt, tmp);
tmp = e;
tmp.y1 = tr[2*rt+1].lf; update(2*rt+1, tmp);
}
calen(rt);
}
int main()
{
int t, i, cnt;
double x1, x2, y1, y2, ans;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
cnt = 1; ans = 0;
for(i = 1; i <= n; i++)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
line[cnt].x = x1; line[cnt].y1 = y1;
line[cnt].y2 = y2; line[cnt].f = 1;
y[cnt++] = y1;
line[cnt].x = x2; line[cnt].y1 = y1;
line[cnt].y2 = y2; line[cnt].f = -1;
y[cnt++] = y2;
}
sort(y+1, y+cnt);
sort(line+1, line+cnt, cmp);
cnt --;
build(1, cnt, 1);
update(1, line[1]);
for(i = 2; i <= cnt; i++)
{
ans += tr[1].more*(line[i].x - line[i-1].x);
update(1, line[i]);
}
printf("%.2lf\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: