遇见poj上最浪漫的题目。。题目里图片以上几百词为一篇模板级英文情书。这情感和细腻的文笔深深地打动了我。。不会写情书的童鞋速度进来学习。传送门

题意:坐标系内有n个星星,每个星星都有一个亮度c (1<= c <= 100),坐标和亮度都已给出。 有一个矩形的窗户(就是个理想化的矩形),四条边与x轴或y轴平行。矩形可以在坐标系内平移,但不可以进行旋转操作。求这个矩形可以框住的星星的亮度之和最大为多少。注意:恰好在边上的星星不算在内。

思路:好吧,这题又是看别人的题解才做出来的,深深自责中。。。思路最主要也是最难想的地方就是,题目中是用矩形框住星星,在实际求解过程中要转化为对于每一颗星星,先找出能框住它的那些矩形(肯定不止一个)在坐标系内能够覆盖的区域。因为矩形可以平移,有无数中情况,但是极限情况就四种,就是星星位于矩形的四个顶点的情况。可以想象出,总区域该是四个矩形构成的一个大矩形。将这个矩形通过某种操作,覆盖上该星星的亮度c。最后的问题就转化为了,求坐标系内覆盖的亮度最大的矩形。这就转化到了用线段树扫描法求矩形面积的问题上了。

但实际解题过程中,只需要考虑星星位于矩形一个顶点时的情况(这里我也有些迷迷糊糊的,我的理解是,对于最后求得的结果,位于四个顶点的情况是等价的。可以想想最后得到的那个矩形里分布着不均匀的星星,可能对于某星星,这个矩形能够通过位于右上角顶点的情况计算出;对于另一个星星,可能就是右下角的情况了,所以从哪个顶点算都一样),这样处理起来也特别简单。

思路核心部分:题目中给出的矩形窗户的长为w,宽为h。现对于每一个星星(x, y),都想象一个以它为左下角顶点且长为w,宽为h的矩形。由于位于矩形边上的星星不算。因此这颗星星实际可以作用到的范围,x轴方向为[x, x+w),y轴方向为[y, y+h)。如果通过自下往上的扫描法,可以沿x轴建线段树,使用cover维护x轴区间内覆盖的亮度,使用tmax维护x轴区间内亮度的最大值。当扫描到一颗星星时,就将一条两端点分别为x, x+w-1(之所以减一,是因为线段树每个叶子表示的区间为该点到下一点之间的区间。),纵坐标为y,权值flag为该星星的亮度c的一条边覆盖到x轴上。但线继续朝上扫描时,当扫描到纵坐标为y+h时,该星星的亮度就不再起作用了。因此,对于每一颗星星,在坐标系内我们还要假象一条边,两端点为x, x+w-1,纵坐标为y+h,权值flag为-c。这样当扫描线到了y+h的高度时,将这条边覆盖到x轴上,便将之前的那条边给抵消了!

这样每往x轴上覆盖一条边,通过线段树维护数据,计算出当前x轴上存在的亮度和的最大值(可以肯定,一定存在一个长为w,宽为h的矩形,它框住的星星亮度和为此时计算出的亮度和最大值),若最大值大于ans,则赋值给ans。最后ans即为结果。

后话:因为x,y的坐标大小可达2^31,因此离散化是必须的。还有,x+w的范围可能超2^31,用int会wa,改成long long就ok了。

 #include<stdio.h>
#include<string.h>
#include<algorithm>
#define maxn 22222
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
int cover[maxn<<], tmax[maxn<<];
long long x[maxn];
struct seg
{
long long l, r, h;
int flag;
seg() {}
seg(long long x1,long long x2,long long y,int s) : l(x1), r(x2), h(y), flag(s) {}
bool operator < (const seg &cmp) const
{
if (h == cmp.h) return flag < cmp.flag;
return h < cmp.h;
}
}ss[maxn];
int bin(long long key,int len,long long x[])
{
int l = , r = len - ;
while (l <= r)
{
int m = (l + r) >> ;
if (key == x[m]) return m;
else if (key < x[m]) r = m - ;
else l = m + ;
}
return -;
}
void PushDown(int rt)
{
if (cover[rt] != )
{
cover[rt<<] += cover[rt];
cover[rt<<|] += cover[rt];
tmax[rt<<] += cover[rt];
tmax[rt<<|] += cover[rt];
cover[rt] = ;
}
}
void PushUp(int rt)
{
tmax[rt] = max(tmax[rt<<], tmax[rt<<|]);
}
void update(int L,int R,int c,int l,int r,int rt)
{
if (L <= l && r <= R)
{
cover[rt] += c;
tmax[rt] += c;
return;
}
PushDown(rt);
int m = (l + r) >> ;
if (L <= m) update(L, R, c, lson);
if (m < R) update(L, R, c, rson);
PushUp(rt);
}
int main()
{
int n, w, h;
//freopen("data.in", "r", stdin);
while (~scanf("%d%d%d",&n,&w,&h))
{
int tot = ;
long long xi, y;
int c;
memset(cover, , sizeof(cover));
memset(tmax, , sizeof(cover));
for (int i = ; i < n; i++)
{
scanf("%lld%lld%d",&xi,&y,&c);
x[tot] = xi;
ss[tot++] = seg(xi, xi + w, y, c);
x[tot] = xi + w;
ss[tot++] = seg(xi, xi + w, y + h, -c);
}
sort(x, x + tot);
sort(ss, ss + tot);
int k = ;
for (int i = ; i < tot; i++)
if (x[i] != x[i-]) x[k++] = x[i];
int ans = ;
for (int i = ; i < tot - ; i++)
{
int l = bin(ss[i].l, k, x);
int r = bin(ss[i].r, k, x) - ;
if (l <= r) update(l, r, ss[i].flag, , k - , );
if (ans < tmax[]) ans = tmax[];
}
printf("%d\n",ans);
}
return ;
}

POJ 2482 Stars in Your Window 离散化+扫描法 线段树应用的更多相关文章

  1. POJ 2482 Stars in Your Window(扫描线+线段树)

    [题目链接] http://poj.org/problem?id=2482 [题目大意] 给出一些点的二维坐标和权值,求用一个长H,宽W的矩形能框住的最大权值之和, 在矩形边缘的点不计算在内 [题解] ...

  2. poj 2482 Stars in Your Window(扫描线)

    id=2482" target="_blank" style="">题目链接:poj 2482 Stars in Your Window 题目大 ...

  3. POJ 2482 Stars in Your Window(线段树)

    POJ 2482 Stars in Your Window 题目链接 题意:给定一些星星,每一个星星都有一个亮度.如今要用w * h的矩形去框星星,问最大能框的亮度是多少 思路:转化为扫描线的问题,每 ...

  4. poj 2482 Stars in Your Window + 51Nod1208(扫描线+离散化+线段树)

    Stars in Your Window Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13196   Accepted:  ...

  5. POJ 2482 Stars in Your Window 线段树扫描线

    Stars in Your Window   Description Fleeting time does not blur my memory of you. Can it really be 4 ...

  6. (中等) POJ 2482 Stars in Your Window,静态二叉树。

    Description Here comes the problem: Assume the sky is a flat plane. All the stars lie on it with a l ...

  7. POJ 2482 Stars in Your Window (线段树+扫描线+区间最值,思路太妙了)

    该题和 黑书 P102 采矿 类似 参考链接:http://blog.csdn.net/shiqi_614/article/details/7819232http://blog.csdn.net/ts ...

  8. POJ 2482 Stars in Your Window

    线段树+离散化+扫描线 AC之后,又认真读了一遍题目,好文章. #include<cstdio> #include<map> #include<algorithm> ...

  9. POJ 2482 Stars in Your Window 线段树

    如果按一般的思路来想,去求窗户能框住的星星,就很难想出来. 如果换一个思路,找出每颗星星能被哪些窗户框住,这题就变得非常简单了. 不妨以每个窗户的中心代表每个窗户,那么每颗星星所对应的窗户的范围即以其 ...

随机推荐

  1. Jmeter 参数化之 CSV Data Set Config 循环读取参数

    对于做接口和性能测试,个人感觉Jmeter是一个非常方便易学的工具,今天随笔记录Jmeter 参数化之 CSV Data Set Config. 首先在开始记录之前,先搞明白2个问题 1.什么是参数化 ...

  2. python - web自动化测试 - 元素操作 - 鼠标键盘

    # -*- coding:utf-8 -*- ''' @project: web学习 @author: Jimmy @file: 鼠标操作.py @ide: PyCharm Community Edi ...

  3. [转]个人对AutoResetEvent和ManualResetEvent的理解

    仅个人见解,不对之处请指正,谢谢. 一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方 ...

  4. Python全栈 MySQL 数据库 (简述 、安装、基本命令)

    ParisGabriel              每天坚持手写  一天一篇  决定坚持几年 为了梦想为了信仰    开局一张图     一个月的python已经结束了  下面就是数据库了   先说M ...

  5. Spring 笔记(三)Bean 装配

    前言 Spring 有两大核心,也就分成两份笔记分别记录. 其一是管理应用中对象之间的协作关系,实现方式是依赖注入(DI),注入依赖的过程也被称为装配(Wiring). 基于 JavaConfig 的 ...

  6. quagga源码学习--BGP协议中的routemap

    路由策略的基础知识 定义 路由策略(Routing Policy)作用于路由,主要实现了路由过滤和路由属性设置等功能,它通过改变路由属性(包括可达性)来改变网络流量所经过的路径. 目的 路由器在发布. ...

  7. HDU 2491

    欢迎参加——BestCoder周年纪念赛(高质量题目+多重奖励) Priest John's Busiest Day Time Limit: 4000/2000 MS (Java/Others)    ...

  8. ocrosoft Contest1316 - 信奥编程之路~~~~~第三关 问题 I: 寻找大富翁

    http://acm.ocrosoft.com/problem.php?cid=1316&pid=8 题目描述 浙江杭州某镇共有n个人,请找出该镇上的前m个大富翁. 输入 输入包含多组测试用例 ...

  9. Asymptotic I Catalan Number

    卡特兰数出现在许多计数问题中. 常见的例子有:$n$ 个节点的有序二叉树,$2n$ 个括号构成的合法括号序列. 在上面所举的两个例子中,很容易看出卡特兰数满足递推: $$ C_{n+1} = \sum ...

  10. 通过CLI命令将ESXi主机进入维护模式

    将主机置于维护模式# vimsh -n -e /hostsvc/maintenance_mode_enter # vim-cmd /hostsvc/maintenance_mode_enter 退出维 ...