您的位置:首页 > 其它

HUD 1255 面积覆盖 线扫描

2015-07-29 09:18 337 查看
求面积交

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <string.h>
#include <map>
#include <set>
using namespace std;
#define maxn 11005
struct line
{
    double x1,x2,h;
    int c;
    line(){}
    line(double xx1,double xx2,double yy1,int cc):
        x1(xx1),x2(xx2),h(yy1),c(cc){}
}s[maxn];
bool clm(line x,line y)
{
    return x.h<y.h;
}
struct node
{
    int l,r;
    double len,len1;//len是该区间覆盖>1次的长度,len1是该区间覆盖等于一次的长度
    int c;
}tree[maxn*4];
double x[maxn];
int n;
void build(int id,int l,int r)
{
    tree[id].l=l;
    tree[id].r=r;
    tree[id].c=0;
    tree[id].len=tree[id].len1=0.0;
    if(l!=r)
    {
        int mid=(l+r)/2;
        build(id*2,l,mid);
        build(id*2+1,mid+1,r);
    }
}
void pushup(int id,int l,int r)
{
    //先处理覆盖一次的长度
    if(tree[id].c)tree[id].len1=x[r]-x[l-1];//若tree[id].c>=1说明该区间完全覆盖
    else if(l==r)tree[id].len1=0.0;
    else tree[id].len1=tree[id*2].len1+tree[id*2+1].len1;//若tree[id].c==0,覆盖一次的长度就左右儿子被覆盖一次的长度

    //再处理覆盖两次以上的长度
    if(tree[id].c>1)
        tree[id].len=x[r]-x[l-1];
    else if(l==r)tree[id].len=0.0;
    else if(tree[id].c==1)//若tree[id].c==1,只能说明该区间没有被完全覆盖两次以上,有可能它的儿子覆盖了两次
        tree[id].len=tree[id*2].len1+tree[id*2+1].len1;//去儿子节点覆盖了一次的长度
    else
        tree[id].len=tree[id*2].len+tree[id*2+1].len;//若tree[id].c==0它被覆盖了0次,但是它儿子可能被覆盖了两次以上,
                                                    //则去它儿子被覆盖两次以上的长度
}
void update(int id,int l,int r,int c)
{
    //if(l<=tree[id].l&&tree[id].r<=r)
    if(l==tree[id].l&&tree[id].r==r)
    {
        tree[id].c+=c;
        pushup(id,tree[id].l,tree[id].r);
    }
    else
    {
        int mid=(tree[id].l+tree[id].r)/2;
        if(r<=mid)update(id*2,l,r,c);
        else if(l>mid)update(id*2+1,l,r,c);
        else
        {
            update(id*2,l,mid,c);
            update(id*2+1,mid+1,r,c);
        }
//        if(l<=mid)update(id*2,l,r,c);
//        if(r>mid)update(id*2+1,l,r,c);
        pushup(id,tree[id].l,tree[id].r);
    }
}

int main()
{
      int i,k,t;
      double x1,x2,y1,y2;
      scanf("%d",&t);
      while(t--)
      {
          scanf("%d",&n);
          k=0;
          for(i=0;i<n;i++)
          {
              scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
              s[k]=line(x1,x2,y1,1);
              x[k]=x1;
              k++;
              s[k]=line(x1,x2,y2,-1);
              x[k]=x2;
              k++;
          }
          sort(s,s+k,clm);
          sort(x,x+k);
          int m=1;
          for(i=1;i<k;i++)
          {
              if(x[i]!=x[i-1])
                x[m++]=x[i];
          }

          build(1,1,m-1);
          double ans=0.0;
          for(i=0;i<k-1;i++)
          {
                int l=lower_bound(x,x+m-1,s[i].x1)-x;
                int r=lower_bound(x,x+m-1,s[i].x2)-x;
                update(1,l+1,r,s[i].c);
                ans+=tree[1].len*(s[i+1].h-s[i].h);
          }

          printf("%0.2f\n",ans);

      }

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: