hdu 1542

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542

题意:

求所给矩形的覆盖面积

题解:

利用扫描线的思想,先将坐标离散化,之后以y轴分成多个矩形求解,可以让下边界+1上边界-1

问题就转化为了:求区间中有多少个非0数,要求支持区间+1 -1操作

我们可以通过维护区间最小值以及最小值的个数来完成这件事情

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include <iostream>
#define maxn 5000
#define INF 59999999
#define eps 1e-6
#define mid (h+t)/2
using namespace std;
struct re 
{
    double a;int b;
}a[maxn],b[maxn];
struct ree
{
    int h,t,x,lazy;
    double sum,tot;
}p[maxn*4];
double c[maxn];
int a1[maxn];
bool cmp(re x,re y)
{
  if (x.a<y.a) return(true); else return(false);
}
void build(int x,int h,int t)
{
    p[x].h=h; p[x].t=t; p[x].x=0;
    if (h==t) 
    {
      p[x].sum=p[x].tot=c[h+1]-c[h];
      return;
    }
    build(x*2,h,mid);
    build(x*2+1,mid+1,t);
    p[x].sum=p[x].tot=p[x*2].sum+p[x*2+1].sum;
}
void updata(int x)
{
        p[x].x=min(p[x*2].x,p[x*2+1].x);
        if (p[x*2].x==p[x*2+1].x)
        {
            p[x].sum=p[x*2].sum+p[x*2+1].sum;
        }
        else
        {
            if (p[x*2].x<p[x*2+1].x) p[x].sum=p[x*2].sum;
            else p[x].sum=p[x*2+1].sum;
        }
        return;
}
void down(int x)
{
    if (p[x].lazy==0) return;
    p[x].x+=p[x].lazy;
    p[x*2].lazy+=p[x].lazy;
    p[x*2+1].lazy+=p[x].lazy;
    p[x].lazy=0;
}
void insert(int x,int h,int t,int sum)
{
    down(x);
    if (p[x].h>t|| p[x].t<h) return;
    if (h<=p[x].h &&p[x].t<=t)
    {
      p[x].lazy+=sum; down(x); return;
    }
    insert(x*2,h,t,sum); insert(x*2+1,h,t,sum);
    updata(x);
}
double query(int x,int h,int t)
{
    down(x);
    if (p[x].h>t||p[x].t<h) return(0);
    if (h<=p[x].t && p[x].t<=t)
    {
        if (p[x].x==0) return(p[x].tot-p[x].sum); else return(p[x].tot);
    }
    return(query(x*2,h,t)+query(x*2+1,h,t));
}
int main()
{int n,o=0;
while (cin>>n&&n!=0)
{
    o++;
  memset(p,0,sizeof(p));
  for (int i=1;i<=2*n;i++) a[i].b=i,b[i].b=i;
  for (int i=1;i<=n;i++)
  {
      cin>>a[2*i-1].a>>b[2*i-1].a>>a[2*i].a>>b[2*i].a;
  }
  sort(a+1,a+1+2*n,cmp);
  sort(b+1,b+1+2*n,cmp); 
  int ll=0; a[0].a=INF;
  for (int i=1;i<=2*n;i++)
  {
      if (abs(a[i].a-a[i-1].a)>eps) ll++;
      a1[a[i].b]=ll;
      c[ll]=a[i].a;
  }
  double ans=0;
    build(1,1,ll-1);
  for (int i=1;i<2*n;i++)
  {
      int pp,tmp=b[i].b;
      if (tmp%2==1) pp=1 ;else pp=-1;
    insert(1,a1[(tmp+1)/2*2-1],a1[(tmp+1)/2*2]-1,pp);
    ans+=(b[i+1].a-b[i].a)*query(1,1,ll-1); 
  }
  cout<<"Test case #"<<o<<endl<<"Total explored area: " ;
  printf("%.2f\n\n",ans);
  }
}
View Code

 

posted @ 2018-01-30 20:40  尹吴潇  阅读(119)  评论(0编辑  收藏  举报