扫描线第一题,第一次交上去居然PE了,好吧,有傻逼了,少加个了个回车.
注意点:
1. 区间分段的时候要分成 [l,mid] 和[mid,r]不是平常一样的[l,mid]和[mid+1,r](因为我们要算的一段线段的长度,也就是说得连续,比如我们要算这一段[1,10],应该把他分成[1,5][5,10],不能[1,5][6,10]);
2.由于上面的mid和平时的线段树不同,所以判断退出的时候是(l+1==r)才退出,因为我们表示的是一段线段,每个值是一个点,如果l等于r的话,就是一个点了,也没意义了.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#define lc idx<<1
#define rc idx<<1|1
#define mid ((l+r)>>1)
#define lson lc,l,mid
#define rson rc,mid,r
#define whole idx,l,r
using namespace std;
const int MAXN=100000+10;
int k;
class Line
{
public:
double x,yu,yd;
int type;
Line(){}
Line(double a,double b,double c,int d) :x(a),yu(b),yd(c),type(d) {}
bool operator <(const Line &a) const
{
return x<a.x;
}
};
vector<Line> line;
vector<double> cor_y;
map<double,int> pj;
class SGtree
{
public:
double len[MAXN<<2];
int cnt[MAXN<<2];
void build(int idx,int l,int r)
{
len[idx]=cnt[idx]=0;
if(l+1==r) return ;
build(lson);
build(rson);
}
void maintain(int idx,int l,int r)
{
if(cnt[idx]>0) len[idx]=cor_y[r]-cor_y[l];
else
{
if(l+1==r) len[idx]=0;
else len[idx]=len[lc]+len[rc];
}
}
void update(int idx,int l,int r,int x,int y,int v)
{
if(x<=l && r<=y)
cnt[idx]+=v;
else
{
if(x<mid) update(lson,x,y,v);
if(y>mid) update(rson,x,y,v);
}
maintain(whole);
}
};
SGtree tree;
int main()
{
// freopen("in","r",stdin);
int n,kcase=1;
while(~scanf("%d",&n) && n)
{
line.clear();
cor_y.clear();
pj.clear();
double a,b,c,d;
for(int i =0; i<n; i++)
{
scanf("%lf %lf %lf %lf",&a,&b,&c,&d);
line.push_back(Line(a,d,b,1));
line.push_back(Line(c,d,b,-1));
cor_y.push_back(b);
cor_y.push_back(d);
}
cor_y.push_back(-100000000);
sort(line.begin(),line.end());
sort(cor_y.begin(),cor_y.end());
k=1;
for(int i=1; i<cor_y.size(); i++)
{
if(cor_y[i]!=cor_y[i-1])
{
pj[cor_y[i]]=k;
cor_y[k++]=cor_y[i];
}
}
double ans=0;
tree.build(1,1,k-1);
tree.update(1,1,k-1,pj[line[0].yd],pj[line[0].yu],line[0].type);
for(int i=1; i<line.size(); i++)
{
ans+=(line[i].x-line[i-1].x)*(tree.len[1]);
tree.update(1,1,k-1,pj[line[i].yd],pj[line[i].yu],line[i].type);
}
printf("Test case #%d\n",kcase++);
printf("Total explored area: %.2f\n\n",ans) ;
}
return 0;
}