POJ1151Atlantis

线段树+离散化


代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=3000;
struct Seg
{
	double l,r,sum;
	int lazy,so[2];
}t[M];
int cnt=2,n;
struct map{double x,y,yy;int flag;}p[M];
double s[M];
bool cmp(map a,map b){return a.x<b.x;}
void push_up(int x)
{
	int ls=t[x].so[0];
	int rs=t[x].so[1];
    if(t[x].lazy>0) t[x].sum=t[x].r-t[x].l;
    else t[x].sum=t[ls].sum+t[rs].sum;
    return ;
}
void built(int l,int r,int x)
{
    if(r-l==1)
    {
        t[x].l=s[l];t[x].r=s[r];
        t[x].so[0]=t[x].so[1]=-1;
        return (void)(t[x].sum=0);
    }
	t[x].l=s[l];t[x].r=s[r];
	int mid=(l+r)>>1;
	t[x].so[0]=++cnt;t[x].so[1]=++cnt;
    built(l,mid,t[x].so[0]);built(mid,r,t[x].so[1]);
    push_up(x);
    return ;
}
void update(double y,double yy,int x,int flag)
{
    if(t[x].l==y&&t[x].r==yy) return (void)(t[x].lazy+=flag,push_up(x));  
    if(t[t[x].so[0]].r>y)
        update(y,min(t[t[x].so[0]].r,yy),t[x].so[0],flag);
    if(t[t[x].so[1]].l<yy)
        update(max(t[t[x].so[1]].l,y),yy,t[x].so[1],flag);
    push_up(x);
    return ;
}
int main()
{
    int cas=1;
    
    while(scanf("%d",&n)&&n)
    {
        double ans=0,x1,y,x2,yy;cnt=2;
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf%lf%lf",&x1,&y,&x2,&yy);
            p[i].x=x1;p[i].y=y;p[i].yy=yy;p[i].flag=1;
            p[i+n].x=x2;p[i+n].y=y;p[i+n].yy=yy;p[i+n].flag=-1;
            s[i+1]=y;s[i+n+1]=yy;
        }
        sort(s+1,s+(2*n+1));sort(p,p+2*n,cmp);
        built(1,2*n,1);
        update(p[0].y,p[0].yy,1,p[0].flag);
        for(int i=1;i<2*n;i++)
        {
            ans+=(p[i].x-p[i-1].x)*t[1].sum;
            update(p[i].y,p[i].yy,1,p[i].flag);
        }
        printf("Test case #%d\nTotal explored area: %.2lf\n\n",cas++,ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ACerAndAKer/article/details/81006323