HUD 1255 面积覆盖 线扫描

来源:互联网 发布:制作地图软件 编辑:程序博客网 时间:2024/06/16 02:08

求面积交

#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 11005struct 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;}


0 0
原创粉丝点击