http://xuyemin520.is-programmer.com/posts/25988
http://hi.baidu.com/nicker2010/item/d88fe842c22163a160d7b9ee
基础扫描线,重写一下
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<math.h>
using namespace std;
#define ll long long
#define N 110
struct node
{
int l,r,cover;
double dl,dr,len;
}tree[8*N];
double yt[2*N];
struct line
{
double y1,y2;
double x;
int flag;
}p[2*N];
void build(int id,int x,int y)
{
tree[id].l=x;
tree[id].r=y;
tree[id].cover=0;
tree[id].dl=yt[x];
tree[id].dr=yt[y];
tree[id].len=0;
if(x+1==y) return ;
int mid=(x+y)>>1;
build(id<<1,x,mid);
build((id<<1)+1,mid,y);
}
bool cmp(line a,line b)
{
return a.x<b.x;
}
void update(int id)
{
if(tree[id].cover>0)
tree[id].len=tree[id].dr-tree[id].dl;
else if(tree[id].l+1==tree[id].r)
tree[id].len=0;
else
tree[id].len=tree[id<<1].len+tree[(id<<1)+1].len;
}
void add(int id,line e)
{
if(tree[id].dl==e.y1 && tree[id].dr==e.y2)
{
tree[id].cover+=e.flag;
update(id);
return ;
}
if(tree[id<<1].dr>=e.y2)
add(id<<1,e);
else if(tree[(id<<1)+1].dl<=e.y1)
add((id<<1)+1,e);
else
{
line t=e;
t.y2=tree[id<<1].dr;
add(id<<1,t);
t=e;
t.y1=tree[(id<<1)+1].dl;
add((id<<1)+1,t);
}
update(id);
}
int main()
{
int n,i,j,k;
int res=0;
while(scanf("%d",&n),n)
{
res++;
int cnt=0;
for(i=0;i<n;i++)
{
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
p[cnt].x=x1;
p[cnt].y1=y1;
p[cnt].y2=y2;
p[cnt].flag=1;
yt[cnt]=y1;
cnt++;
p[cnt].x=x2;
p[cnt].y1=y1;
p[cnt].y2=y2;
p[cnt].flag=-1;
yt[cnt]=y2;
cnt++;
}
sort(p,p+cnt,cmp);
sort(yt,yt+cnt);
build(1,0,cnt-1);
double sum=0;
for(i=0;i<cnt-1;i++)
{
add(1,p[i]);
sum+=(p[i+1].x-p[i].x)*tree[1].len;
}
printf("Test case #%d\n",res);
printf("Total explored area: %.2lf\n",sum);
printf("\n");
}
}
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 110
double x1,Y1,x2,y2;
struct node
{
double len;
int cover,l,r;
}tree[6*N];
double yy[2*N];
struct pos
{
double x,y1,y2;
int flag;
}line[2*N];
bool cmp(pos a,pos b)
{
return a.x<b.x;
}
void build(int id,int x,int y)
{
tree[id].l=x;
tree[id].r=y;
tree[id].len=0;
tree[id].cover=0;
if(x+1==y)
return ;
int mid=(x+y)>>1;
build(id<<1,x,mid);
build((id<<1)+1,mid,y);
}
int cnt;
int find(double x)
{
int l=0,r=cnt-1;
while(l<=r){
int mid=(l+r)>>1;
if(yy[mid]==x) return mid;
else if(yy[mid]>x) r=mid-1;
else l=mid+1;
}
return l;
}
void add(int id,int x,int y,int h)
{
if(tree[id].l==x && tree[id].r==y)
{
tree[id].cover+=h;
if(tree[id].cover>0)
tree[id].len=yy[tree[id].r]-yy[tree[id].l];
else if(tree[id].l+1==tree[id].r) tree[id].len=0;
else tree[id].len=tree[id<<1].len+tree[(id<<1)+1].len;
return ;
}
else {
int mid=(tree[id].l+tree[id].r)>>1;
if(mid>=y) add(id<<1,x,y,h);
else if(mid<=x) add((id<<1)+1,x,y,h);
else{
add(id<<1,x,mid,h);
add((id<<1)+1,mid,y,h);
}
if(tree[id].cover>0)
tree[id].len=yy[tree[id].r]-yy[tree[id].l];
else if(tree[id].l+1==tree[id].r) tree[id].len=0;
else tree[id].len=tree[id<<1].len+tree[(id<<1)+1].len;
}
}
int main()
{
int n,i,j,k,ans=0;
while(cin>>n,n)
{
ans++;
cnt=0;
for(i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&Y1,&x2,&y2);
yy[cnt]=Y1;
line[cnt].flag=1;
line[cnt].x=x1;
line[cnt].y1=Y1;
line[cnt++].y2=y2;
yy[cnt]=y2;
line[cnt].flag=-1;
line[cnt].x=x2;
line[cnt].y1=Y1;
line[cnt++].y2=y2;
}
sort(yy,yy+cnt);
sort(line,line+cnt,cmp);
build(1,0,cnt-1);
double sum=0;
for(i=0;i<cnt-1;i++)
{
int a=find(line[i].y1);
int b=find(line[i].y2);
add(1,a,b,line[i].flag);
sum+=(line[i+1].x-line[i].x)*tree[1].len;
}
printf("Test case #%d\n",ans);
printf("Total explored area: ");
printf("%.2lf\n",sum);
printf("\n");
}
}
上面的add函数是更新到段的。。应该比较省时间
然后又写了一个更新到点的,,呵呵,比较好写+好理解
void add(int id,int x,int y,int h)
{
if(tree[id].l+1==tree[id].r)
{
tree[id].cover+=h;
if(tree[id].cover) tree[id].len=yy[tree[id].r]-yy[tree[id].l];
else tree[id].len=0;
return ;
}
int mid=(tree[id].l+tree[id].r)>>1;
if(mid>=y) add(id<<1,x,y,h);
else if(mid<=x) add((id<<1)+1,x,y,h);
else{
add(id<<1,x,mid,h);
add((id<<1)+1,mid,y,h);
}
tree[id].len=tree[id<<1].len+tree[(id<<1)+1].len;
}