hdu 1542 Atlantis (扫描线+离散化线段树求多矩形总面积)

题目链接:哆啦A梦传送门

题意:给n个矩形,求它们的总面积,覆盖的只算一次。每个矩形给出左下点和右上点。

参考博客1:

参考博客2

 

扫描线从下往上扫描,每次求出该扫描线的有效长度,再与两条线之间的高度相乘就是最后的面积。

线段树更新,遇到该边为矩形的下边就加进去,遇到该边为矩形的上边就减掉。

 

代码:

#include
#include
#include

using namespace std;
typedef long long LL;
const int N=1000;

struct node{
    double l,r,h; ///每条线的左右x端点,该线的纵坐标
    int d; ///d=1为下边,d=-1为上边
}a[N];

bool cmp(node X,node Y)
{
    return X.h>1;
        build(root*2,l,mid);
        build(root*2+1,mid+1,r);
    }
}

void pushup(int root)
{
    if(tree[root].s){ ///该节点被完全覆盖
        tree[root].len=x[tree[root].tr]-x[tree[root].tl-1];
    }
    else if(tree[root].tl==tree[root].tr){ ///这是一个点而不是一条线段
        tree[root].len=0;
    }
    else {///是一条没有被完全覆盖的区间,合并左右子节点
        tree[root].len=tree[root*2].len+tree[root*2+1].len;
    }
}

void update(int root,int ql,int qr,int val)
{
    int tl=tree[root].tl,tr=tree[root].tr;

    if(ql<=tl&&tr<=qr){ ///更新区间包含该节点区间,说明该节点区间被完全覆盖
        tree[root].s+=val;
        pushup(root);
        return;
    }
    int mid=(tl+tr)>>1;
    if(mid>=ql) update(root*2,ql,qr,val);
    if(mid

 

 

你可能感兴趣的:(线段树)