POJ 1151 Atlantis (scan line method, line segment tree, discretization)
Blue Book Line Segment Tree Exercises POJ 1151 Atlantis
Question Meaning: Given two coordinate points (x, y) (x, y) at the bottom left and top right of n rectangles(x,y ) , find their area and (total area)
data range:n: 100, x / y: 1 e 5 n: 100, x/y: 1e5n:100、x/y:1e5
Idea: I'm so sleepy now and write tomorrow^^
LL n;
struct SegmentTree{
int l,r,add;
double dat;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define dat(x) tree[x].dat
#define add(x) tree[x].add
}tree[maxn*8];
struct node{
double x,y,z;
int c,zz,yy;
bool operator <(const node aa)const{
return x<aa.x;
}
}a[maxn*2];
double b[maxn*2];
void build(int p,int l,int r){
l(p)=l,r(p)=r;
dat(p)=0;add(p)=0;
if(l==r) {
return;}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
}
void lazy(int p){
if(add(p)){
dat(p*2)+=add(p);
dat(p*2+1)+=add(p);
add(p*2)+=add(p);
add(p*2+1)+=add(p);
add(p)=0;
}
}
void change(int p,int l,int r,double z){
if(l<=l(p)&&r>=r(p)){
dat(p)=((add(p)+=z)?b[r(p)+1]-b[l(p)]:0);}
if(l(p)==r(p)){
return;}
int mid=(l(p)+r(p))/2;
if(l<=mid) change(p*2,l,r,z);
if(r>mid) change(p*2+1,l,r,z);
if(add(p))dat(p)=b[r(p)+1]-b[l(p)];
else dat(p)=dat(2*p)+dat(2*p+1);
}
LL ask(int p,int l,int r)
{
if(l<=l(p)&&r>=r(p)) return dat(p);
lazy(p);
int mid=(l(p)+r(p))/2;
LL ans=0;
if(l<=mid) ans+=ask(p*2,l,r);
if(r>mid) ans+=ask(p*2+1,l,r);
return ans;
}
int main(){
LL co,sum=0;
double ans;
while(scanf("%lld",&n)!=EOF&&n){
ans=0;
for(int i=1;i<=n;i++){
scanf("%lf%lf%lf%lf",&a[2*i-1].x,&a[2*i-1].y,&a[i*2].x,&a[2*i].z);
b[i*2-1]=a[2*i].y=a[2*i-1].y;
b[2*i]=a[2*i-1].z=a[2*i].z;
a[2*i].c=-1;
a[2*i-1].c=1;
}
n*=2;
sort(b+1,b+1+n);
co=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++){
a[i].yy=lower_bound(b+1,b+co+1,a[i].y)-b;
a[i].zz=lower_bound(b+1,b+1+co,a[i].z)-b;
}
sort(a+1,a+1+n);
build(1,1,co-1);
for(int i=1;i<=n;i++){
change(1,a[i].yy,a[i].zz-1,a[i].c);
ans+=(a[i+1].x-a[i].x)*tree[1].dat;
}
printf("Test case #%lld\nTotal explored area: %.2f\n\n",++sum,ans);
}
}