矩形面积的并(交)

来源:互联网 发布:linux打开命令行窗口 编辑:程序博客网 时间:2024/04/28 01:31
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define MAXN 22222#define MAXM 5555#define INF 100000007#define lch(x) x<<1#define rch(x) x<<1|1#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int N=1000002;double tmp[N];double bin[N];int n;int cnt;int tot;int lsize;struct Node{    int l,r;    double ylen;//并    double yylen;//交    int ncover;//全部覆盖} tree[N*4];void built(int l,int r,int fa){    tree[fa].l=l;    tree[fa].r=r;    tree[fa].ncover=tree[fa].ylen=tree[fa].yylen=0;    if(l==r-1)        return ;    int mid=(r+l)/2;    built(l,mid,fa<<1);    built(mid,r,fa<<1|1);}void update1(int fa)//面积的并{    int r=tree[fa].r;    int l=tree[fa].l;    if(tree[fa].ncover>0)        tree[fa].ylen=bin[r]-bin[l];    else if(l+1==r)        tree[fa].ylen=0;    else        tree[fa].ylen=tree[fa<<1].ylen+tree[fa<<1|1].ylen;}void update2(int fa)//面积的交{    int r=tree[fa].r;    int l=tree[fa].l;    if(tree[fa].ncover>=2)        tree[fa].yylen=bin[r]-bin[l];    else if(l+1=r)        tree[fa].yylen=0;    else if(tree[fa].ncover==1)        tree[fa].yylen=tree[fa<<1].ylen+tree[fa<<1|1].ylen;    else        tree[fa].yylen=tree[fa<<1].yylen+tree[fa<<1|1].yylen;}void insert(int l,int r,int fa,int val){    if(l<=tree[fa].l&&tree[fa].r<=r)    {        tree[fa].ncover+=val;        update1(fa);//并        //update2(fa);//交        return ;    }    int mid=(tree[fa].l+tree[fa].r)/2;    if(l<mid)        insert(l,r,fa<<1,val);    if(r>mid)        insert(l,r,fa<<1|1,val);    update1(fa);//并    update2(fa);//交}struct Line{    double x,y1,y2;    int flag;    Line() {};    Line(double _x,double _y1,double _y2,double _flag )    {        x=_x;        y1=_y1;        y2=_y2;        flag=_flag;    }} line[N];bool cmp(Line a,Line b){    return a.x<b.x;}struct retangle{    double x1,y1;    double x0,y0;} ret[N];void disperse(){    tot=0;    sort(tmp,tmp+cnt);    bin[tot++]=tmp[0];    for(int i=1; i<cnt; i++)    {        if(tmp[i]!=tmp[i-1])            bin[tot++]=tmp[i];    }}int binary(double num){    int l=0;    int r=tot-1;    int ans;    while(l<=r)    {        int mid=(l+r)/2;        if(bin[mid]>=num)        {            ans=mid;            r=mid-1;        }        else            l=mid+1;    }    return ans;}int main(){    int t=1;    while(scanf("%d",&n)!=EOF)    {        cnt=0;        if(!n)break;        double x0,y0,x1,y1;        for(int i=0; i<n; i++)        {            scanf("%lf%lf%lf%lf",&x0,&y0,&x1,&y1);            ret[i].x0=x0;            ret[i].y0=y0;            tmp[cnt++]=y0;            ret[i].x1=x1;            ret[i].y1=y1;            tmp[cnt++]=y1;        }        /* for(int i=0;i<n;i++)         {             cout<<" ret : I "<<i<<endl ;             cout<<ret[i].x0<<" "<<ret[i].y0<<" "<<ret[i].x1<<" "<<ret[i].y1<<endl;         }*/        disperse();//        for(int i=0; i<tot; i++)//            cout<<bin[i]<<" ";//        cout<<endl;        lsize=0;        for(int i=0; i<n; i++)        {            x0=ret[i].x0;            x1=ret[i].x1;            int yy1=binary(ret[i].y0);            int yy2=binary(ret[i].y1);            //cout<<" i : "<<i<<" "<<x0<<" "<<x1<<" "<<y1<<" "<<y2<<" "<<endl;            line[lsize++]=Line(x0,yy1,yy2,1);            line[lsize++]=Line(x1,yy1,yy2,-1);        }        sort(line ,line +lsize,cmp);        /*for(int i=0;i<lsize;i++)        {            cout<<" i: "<<i<<endl;            cout<<line[i].x<<" "<<line[i].y1<<" "<<line[i].y2<<" "<<line[i].flag;            cout<<endl;        }*/        //cout<<tot<<endl;        built(0,tot-1,1);        double ans=0.0;        for(int i=0; i<lsize; i++)        {            if(i)            {                ans+=(line[i].x-line[i-1].x)*(tree[1].ylen);            }            insert(line[i].y1,line[i].y2,1,line[i].flag);        }        printf("Test case #%d\n",t++);        printf("Total explored area: %.2f\n\n",ans);    }    return 0;}


原创粉丝点击