目录:
题目:
分析:
为题目给的矩形的坐标是浮点型的,所以毫无疑问要离散化,我们以
y
y
轴坐标来建立线段树(当然也可以以轴,这样的话扫描线是上下方向的了),然后
zb
z
b
表示扫描线的下一个位置。求面积的就是
ans+=(zb[i].x−zb[i−1].x)∗t[1].cnt
a
n
s
+
=
(
z
b
[
i
]
.
x
−
z
b
[
i
−
1
]
.
x
)
∗
t
[
1
]
.
c
n
t
。其实说白了扫描线就是一个区间操作的线段树:不过节点存的是
c
c
(这个整个的区间被覆盖的次数,如果为,则这个整区间未被完全覆盖),
cnt
c
n
t
是整个区间所覆盖的长度。每次只需要更新这两个值就好了,设矩形的左边的权值是
1
1
,右边的权值是,每一条边覆盖是,总是带着权值覆盖的。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#define LL long long
#define h happy
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
struct node{
double x,y1,y2;
int f;
}zb[205];
bool cmp(node x,node y)
{
return x.x<y.x;
}
struct segment_tree{
int l,r,c;
double lc,rc,cnt;
}t[805];
double y[205];
void build(int p,int l,int r)
{
t[p].l=l;t[p].r=r;
t[p].cnt=t[p].c=0;
t[p].lc=y[l];t[p].rc=y[r];
if(l+1==r) return;
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid,r);
return;
}
void pushup(int p)
{
if(t[p].c)
{
t[p].cnt=t[p].rc-t[p].lc;
return;
}
if(t[p].l+1==t[p].r) t[p].cnt=0;
else t[p].cnt=t[p*2].cnt+t[p*2+1].cnt;
return;
}
void change(int p,node e)
{
if(t[p].lc==e.y1&&t[p].rc==e.y2)
{
t[p].c+=e.f;
pushup(p);
return;
}
int mid=(t[p].l+t[p].r)>>1;
if(e.y2<=y[mid]) change(p*2,e);
else if(e.y1>=y[mid]) change(p*2+1,e);
else
{
node line=e;
line.y2=y[mid];
change(p*2,line);
line=e;
line.y1=y[mid];
change(p*2+1,line);
}
pushup(p);
return;
}
int main()
{
int n=read(),k=0;
while(n)
{
int cnt=0;
printf("Test case #%d\n",++k);
for(int i=1;i<=n;i++)
{
double a,b,c,d;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
zb[++cnt].x=a;zb[cnt].y1=b;zb[cnt].y2=d;zb[cnt].f=1;
y[cnt]=b;
zb[++cnt].x=c;zb[cnt].y1=b;zb[cnt].y2=d;zb[cnt].f=-1;
y[cnt]=d;
}
sort(zb+1,zb+1+cnt,cmp);
sort(y+1,y+1+cnt);
build(1,1,cnt);
double ans=0;
change(1,zb[1]);
for(int i=2;i<=cnt;i++)
{
ans+=t[1].cnt*(zb[i].x-zb[i-1].x);
change(1,zb[i]);
}
printf("Total explored area: %.2lf\n\n",ans);
n=read();
}
return 0;
}