hdu 1542线段树(成段更新+离散化)

来源:互联网 发布:风花雪月歌词解析知乎 编辑:程序博客网 时间:2024/05/16 16:59

第一次做线段成段更新的题,这题需要离散化。

题意:给出几个矩形,求其覆盖面积。

思路:先离散化x坐标,然后加入矩形的上下边,对矩形上下边根据高度进行排序后。建树,从最高的边开始更新线段树,然后就是通过给每条边赋值上边-1下边1,通过节点中

iosum来判断每次线段树中的有效边,每次ans+=有效边*下一层边的高度,最后得出答案。

代码:

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <memory.h>#define lson l,m,rt<<1#define rson m,r,rt<<1|1using namespace std;double posx[2001];//对x轴进行离散化int mx,me;struct edge{    double x1,x2,y;    int io;//矩形下边的度为1,矩形上边的度为-1(暂且叫作度)} ee[2001]; //对变进行高度排序struct node{    int iosum;//边的度和    double  with;//有效高度} num[8888];int cmp1(const void *a,const void *b){    return *(double *)a>*(double *)b?1:-1;}int cmp2(const void *a,const void *b){    return (*(edge *)a).y>(*(edge *)b).y?1:-1;}int bin(double x){    int low=0,high=mx-1,mid;    while(low<=high)    {        mid=(low+high)>>1;        if(posx[mid]==x) return mid;        else if(posx[mid]>x) high=mid-1;        else low=mid+1;    }    return -1;}void updata(int a,int b,int io,int l,int r,int rt){    if(a<=l&&r<=b)    {        num[rt].iosum+=io;        if(num[rt].iosum)num[rt].with=posx[r]-posx[l];      //////        else if(l+1==r)num[rt].with=0;                      //////        else num[rt].with=num[rt<<1].with+num[rt<<1|1].with;//////        return;    }    int m=(l+r)>>1;    if(a<m)updata(a,b,io,lson);    if(b>m)updata(a,b,io,rson);    if(num[rt].iosum)num[rt].with=posx[r]-posx[l];      //////    else if(l+1==r)num[rt].with=0;                      //////    else num[rt].with=num[rt<<1].with+num[rt<<1|1].with;//////}int main(){    int n,i,ca=1,a,b;    double x1,x2,y1,y2,res;    while(1)    {        scanf("%d",&n);        if(n==0)break;        me=mx=0;        for(i=0; i<n; i++)        {            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);            posx[mx++]=x1;            posx[mx++]=x2;            ee[me].x1=x1;            ee[me].x2=x2;            ee[me].y=y1;            ee[me++].io=1;            ee[me].x1=x1;            ee[me].x2=x2;            ee[me].y=y2;            ee[me++].io=-1;        }        qsort(posx,mx,sizeof(posx[0]),cmp1);        for(i=1,mx=1; i<2*n; i++)            if(posx[i]!=posx[i-1])posx[mx++]=posx[i];        qsort(ee,me,sizeof(ee[0]),cmp2);        memset(num,0,sizeof(node)*8888);        res=0;        for(i=0; i<me-1; i++)        {            a=bin(ee[i].x1);            b=bin(ee[i].x2);            updata(a,b,ee[i].io,0,mx-1,1);            res+=num[1].with*(ee[i+1].y-ee[i].y);        }        printf("Test case #%d\n",ca++);        printf("Total explored area: %.2lf\n\n",res);    }    return 0;}


原创粉丝点击