POJ 2482 线段树 离散化 扫描线 矩阵最大权值

题意:给出n个星星的坐标,每个星星有一个亮度,给出一个矩形的长和宽,问矩形能包括的星星的最大亮度和(不包括边框)。

思路: 平面上有若干个区域,每个区域都带有一个权值,求在那个实际上重叠的区域权值和最大。使用扫描线算法,取出每个区域的左右边界,保存2个四元组,(x,y,y+h,c) (x+w,y,y+h,-c),按照第一维的大小排序。同时关于y建立一颗线段树,维护区间最大值max1,可以认为线段树上的一个值y代表区间[y,y+1] 而区间[y,y+1+h]表示线段树中的y y+1 y+2…y+h这样线段树所维护的值便是由几个数字构成的序列了。。

逐一扫描每个四元组,在线段树中执行区间修改(可以使用延迟标记)把[y1,y2]中的每个数加c,然后用根节点更新答案

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define MAXN 205
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2,r,rt<<1|1
struct Line   //四元组
{
    int x,y1,y2;
    int flag;
}c[MAXN];
struct Node   //关于纵坐标y建立起一颗线段树
{
    int l,r;//线段树的左右整点 
    int max1;//max1记录最大值
    int lazy;//
    //len用来计算实在的长度,rf,lf分别是对应的左右真实的浮点数端点
}a[MAXN*3];
int cnt,numy,max1;
double y[MAXN];//记录y坐标的数组
bool cmp(Line a,Line b)//扫描线算法排序的函数
{
    if(a.x!=b.x)
      return a.x < b.x;
    else
      return a.flag>1;
    Build(rt<<1,l,mid);
    Build(rt<<1|1,mid,r);//递归构造
}
void update(int L,int R,int K,int rt)//加入线段e,后更新线段树
{
    if(L<=a[rt].l&&a[rt].r<=R){
        a[rt].lazy+=K;
        a[rt].max1+=K;
        return ;
    }
    if(L

 

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