zoukankan      html  css  js  c++  java
  • hdu 1542线段树(成段更新+离散化)

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

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

    思路:先离散化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|1
    using 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;
    }


  • 相关阅读:
    ASP.NET 篇
    .NET Core 篇
    JS-CSS篇
    IIS使用篇
    WebService篇
    电脑使用篇
    数据库使用篇
    正则表达式篇
    Linux学习篇
    Leetcode 198. 打家劫舍 dp
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134138.html
Copyright © 2011-2022 走看看