线段树-矩形面积求并

来源:互联网 发布:腾讯社交网络算法大赛 编辑:程序博客网 时间:2024/06/10 09:40

题目链接

题目描述:

给定很多个矩形,给定方式是对角线坐标点.求面积的并。

大致思路:

扫描线+线段树;

#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>#include <string>#include <stdlib.h>#include <math.h>#include <time.h>using namespace std;typedef long long int LL;const int INF=2e9+1e8;const int maxn=1e6+10;struct Date{    double l,r,high;    int flag; //false 为 下面的边} data[maxn];double myh[maxn],input[maxn];int n,k;int getid(double x){    return lower_bound(myh+1,myh+k,x)-myh;}/****  线段树**/struct Seg{    int l,r,val;    double res;} Tree[maxn];void build(int i,int l,int r){    Tree[i].l=l,Tree[i].r=r;    Tree[i].val=0,Tree[i].res=0;    if(l==r) return ;    int mid=(l+r)>>1;    build(i<<1,l,mid);    build(i<<1|1,mid+1,r);}void deal(int i){    if(Tree[i].val) Tree[i].res=myh[Tree[i].r+1]-myh[Tree[i].l];    else if(Tree[i].l==Tree[i].r) Tree[i].res=0.;    else Tree[i].res=Tree[i<<1].res+Tree[i<<1|1].res;}void update(int i,int l,int r,int x) // 更新区间,并维护投影长度和,{    if(l>r) return ;    if(Tree[i].l==l&&Tree[i].r==r)    {        Tree[i].val+=x;        deal(i);        return ;    }    int mid=(Tree[i].l+Tree[i].r)>>1;    if(r<=mid) update(i<<1,l,r,x);    else if(l>mid) update(i<<1|1,l,r,x);    else update(i<<1,l,mid,x),update(i<<1|1,mid+1,r,x);    deal(i);}double solve(){    double ans=0;    update(1,getid(data[0].l),getid(data[0].r)-1,1);    for(int i=1; i<2*n; i++)    {        ans+=Tree[1].res*(data[i].high-data[i-1].high);        update(1,getid(data[i].l),getid(data[i].r)-1,data[i].flag);    }    return ans;}bool cmp(Date a,Date b){    return a.high<b.high;}int main(){//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);    while(scanf("%d",&n)!=EOF)    {        if(n==0) return 0;        for(int i=0; i<n; i++)        {            double x1,y1,x2,y2;            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);            data[i].l=x1,data[i].r=x2,data[i].high=y1,data[i].flag=1;            data[n+i].l=x1,data[i+n].r=x2,data[n+i].high=y2,data[i+n].flag=-1;            input[i]=x1,input[i+n]=x2;        }        sort(data,data+2*n,cmp);// 对y进行排序;        sort(input,input+2*n);//将x进行排序,离散        k=1;        myh[k++]=input[0];        for(int i=1; i<2*n; i++)            if(input[i]!=input[i-1]) myh[k++]=input[i];        build(1,1,k-1);        printf("%.2lf\n",solve());    }    return 0;}
原创粉丝点击