poj 2482 Stars in Your Window(线段树+离散化+扫描线)
来源:互联网 发布:mac上能玩的热门网游 编辑:程序博客网 时间:2024/04/30 12:31
原文地址:poj 2482 Stars in Your Window(线段树+离散化+扫描线) 作者:匆匆过客
题意:在一个平面内有N个星星,每个星星都在一个亮度值,用一个W*H的矩形去围这些星星,(边上的不算)求能得到的最大亮度值。
思路:想了很久一直不懂 只能看别人的解题报告 。。。。
原来只要转换一下,就能把其转换为求线段区间的最大值 每个星星所能影响的范围[(x,y),(x+w-1,y+h-1)]且有一权值它们重合就表示 能被这个矩形框在一起,也就是说,只要求出重合的矩形的权值最大就行了。
以x从小到大排序,y值离散化,投影到y轴上,那么对于每个星星的纵坐标,y,y+h-1就是每个星星可以影响到的矩形然后x,x+w-1就是一个进入事件和一个出去事件,其所带的值互为相反数. node[1].sum 保存当前的最大值当所有的矩形都遍历一遍 取其中的最大值就是ans
PS:看了讨论板说的,要用__int64 但我只把x,y,sum,add的值定义为__int64 其余为int 但 死活WA 本人认为其它的变量按题目要求是不会超过int的范围,而且也有人说 全部都用int也能过, 但在无数次WA之后,实在找不出原因,索性把全部变量都定义为__int64 就AC了 = = 。。。。我还能说什么呢,不知代码哪里写挫了。
//3008K 141MS
#include <stdio.h>
#include <algorithm>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define Max 10010
using namespace std;
struct line
{
__int64x,y1,y2,val;
}seg[Max*2];
struct tree
{
intl,r; //这两变量我觉得真的不可能超过int
__int64sum,add; //sum是该结点的最大亮度值,add是该区间被覆盖的值 用于延迟更新
}node[Max*8];
__int64 y[Max*2];
bool cmp (line a,line b) //x从小到大,x相等,左边的边在前 因为是x+w-1
{
if (a.x< b.x)
return true;
if (a.x ==b.x&&a.val >b.val)
return true;
returnfalse;
}
void Build (__int64 left,__int64 right,int u)
{
node[u].l =left;
node[u].r =right;
node[u].sum= node[u].add = 0;
if (left ==right)
return ;
int mid =(left + right)>>1;
Build(left,mid,L(u));
Build(mid+1,right,R(u));
}
__int64 max (__int64 a,__int64 b)
{
return a> b ? a : b;
}
void getdown (int u)
{
node[L(u)].sum += node[u].add;
node[L(u)].add += node[u].add;
node[R(u)].sum += node[u].add;
node[R(u)].add += node[u].add;
node[u].add= 0;
}
void update (__int64 left,__int64 right,__int64 val,intu) //都是常归套路,也就没什么好说
{ //的了
if (left ==y[node[u].l] && y[node[u].r] ==right)
{
node[u].sum += val;
node[u].add += val;
return ;
}
if(node[u].l == node[u].r)
return ;
if(node[u].add)
getdown (u);
int mid =(node[u].l + node[u].r)>>1;
if (right<= y[mid])
update (left,right,val,L(u));
else if(left >= y[mid+1])
update (left,right,val,R(u));
else
{
思路:想了很久一直不懂 只能看别人的解题报告 。。。。
原来只要转换一下,就能把其转换为求线段区间的最大值 每个星星所能影响的范围[(x,y),(x+w-1,y+h-1)]且有一权值它们重合就表示 能被这个矩形框在一起,也就是说,只要求出重合的矩形的权值最大就行了。
以x从小到大排序,y值离散化,投影到y轴上,那么对于每个星星的纵坐标,y,y+h-1就是每个星星可以影响到的矩形然后x,x+w-1就是一个进入事件和一个出去事件,其所带的值互为相反数. node[1].sum 保存当前的最大值当所有的矩形都遍历一遍 取其中的最大值就是ans
PS:看了讨论板说的,要用__int64 但我只把x,y,sum,add的值定义为__int64 其余为int 但 死活WA 本人认为其它的变量按题目要求是不会超过int的范围,而且也有人说 全部都用int也能过, 但在无数次WA之后,实在找不出原因,索性把全部变量都定义为__int64 就AC了 = = 。。。。我还能说什么呢,不知代码哪里写挫了。
//3008K
#include <stdio.h>
#include <algorithm>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define Max 10010
using namespace std;
struct line
{
}seg[Max*2];
struct tree
{
}node[Max*8];
__int64 y[Max*2];
bool cmp (line a,line b) //x从小到大,x相等,左边的边在前 因为是x+w-1
{
}
void Build (__int64 left,__int64 right,int u)
{
}
__int64 max (__int64 a,__int64 b)
{
}
void getdown (int u)
{
}
void update (__int64 left,__int64 right,__int64 val,intu)
{