矩形面积的并(交)

#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|1
using 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;
}


你可能感兴趣的:(struct,tree,ini,insert,include)