zoukankan      html  css  js  c++  java
  • HDU 1255 覆盖的面积(线段树+扫描线)

    题目地址:HDU 1255

    这题跟面积并的方法非常像,仅仅只是须要再加一个变量。

    刚開始我以为直接用那个变量即可,仅仅只是推断是否大于0改成推断是否大于1。可是后来发现了个问题,由于这个没有下放,没延迟,比方,在父节点上加了一次1,在该父节点的子节点上又加了一次1,可是这时候全部的结点仍然没有达到2的,可是实际上子节点已经达到2了。这时候能够再加一个变量。那个变量用来保存覆盖数大于等于0的情况。这种话当计算大于1的覆盖节点的时候,当推断为1的时候就要加上子节点的全部情况,由于字节点是大于0的,加上子节点的说明该父节点也是大于1的。

    代码例如以下:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <stdlib.h>
    #include <math.h>
    #include <ctype.h>
    #include <queue>
    #include <map>
    #include <set>
    #include <algorithm>
    
    using namespace std;
    #define lson l, mid, rt<<1
    #define rson mid+1, r, rt<<1|1
    int lazy[10000], cnt;
    double sum[10000], c[10000], once[10000];
    struct node
    {
        double l, r, h;
        int f;
    } edge[100000];
    int cmp(node x, node y)
    {
        return x.h<y.h;
    }
    void add(double l, double r, double h, int f)
    {
        edge[cnt].l=l;
        edge[cnt].r=r;
        edge[cnt].h=h;
        edge[cnt++].f=f;
    }
    void PushUp(int l, int r, int rt)
    {
        if(lazy[rt]>=2)
        {
            once[rt]=sum[rt]=c[r+1]-c[l];
        }
        else if(lazy[rt]==1)
        {
            once[rt]=c[r+1]-c[l];
            if(l==r)
            {
                sum[rt]=0;
            }
            else
                sum[rt]=once[rt<<1]+once[rt<<1|1];
        }
        else
        {
            if(l==r)
                once[rt]=sum[rt]=0;
            else
            {
                once[rt]=once[rt<<1]+once[rt<<1|1];
                sum[rt]=sum[rt<<1]+sum[rt<<1|1];
            }
        }
    }
    void update(int ll, int rr, int x, int l, int r,int rt)
    {
        if(ll<=l&&rr>=r)
        {
            lazy[rt]+=x;
            PushUp(l,r,rt);
            return ;
        }
        int mid=l+r>>1;
        if(ll<=mid) update(ll,rr,x,lson);
        if(rr>mid) update(ll,rr,x,rson);
        PushUp(l,r,rt);
    }
    int erfen(double x, int high)
    {
        int low=0, mid;
        while(low<=high)
        {
            mid=low+high>>1;
            if(c[mid]==x)
                return mid;
            else if(c[mid]>x)
                high=mid-1;
            else
                low=mid+1;
        }
    }
    int main()
    {
        int t, n, i, j, k;
        double x1, x2, y1, y2, ans;
        scanf("%d",&t);
        while(t--)
        {
            ans=0;
            memset(sum,0,sizeof(sum));
            memset(lazy,0,sizeof(lazy));
            memset(once,0,sizeof(once));
            scanf("%d",&n);
            k=0;
            cnt=0;
            for(i=0; i<n; i++)
            {
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                c[k++]=x1;
                c[k++]=x2;
                add(x1,x2,y1,1);
                add(x1,x2,y2,-1);
            }
            sort(edge,edge+2*n,cmp);
            sort(c,c+k);
            for(i=0; i<2*n-1; i++)
            {
                int l=erfen(edge[i].l,2*n-1);
                int r=erfen(edge[i].r,2*n-1);
                //printf("%d %d
    ",l,r);
                update(l,r-1,edge[i].f,0,2*n-1,1);
                ans+=sum[1]*(edge[i+1].h-edge[i].h);
                //printf("%.2lf   %.2lf
    ",sum[1],edge[i+1].h-edge[i].h);
            }
            printf("%.2lf
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    TiDB架构特性
    TiDB入门
    ansible安装nginx
    linux命令之cowsay
    KeepAlived 搭建高可用的HAProxy集群
    HAProxy 实现镜像队列的负载均衡
    RabbitMQ高可用集群介绍
    docker安装phpMyAdmin
    centos7安装RabbitMQ
    Vim轻量级查看Java代码
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6866054.html
Copyright © 2011-2022 走看看