题面

Poj

题解

下面内容引用自"李煜东 《算法竞赛进阶指南》"(对原文略有缩减,侵删):

因为矩形的大小固定,所以矩形可以由它的任意一个顶点唯一确定。我们可以考虑把矩形的右上角顶点放在什么位置,圈住的星星亮度总和最大。

所以,对于一颗星星,能够覆盖住这颗星星的右上角的位置在区间$[x,y]-[x+w,y+h]$之间,但是由于边界上的星星不算,所以不妨将星星变为$[x-0.5,y-0.5]$,于是右上角变为$[x+w-1,y+h-1]$。

问题就转化成了:平面上有若干个区域,每个区域都带有一个权值,求在哪个坐标上重叠的区域权值和最大。可以用扫描线算法来解决。

具体来说,将一颗星星抽象成一个矩形,取出左右边界(四元组):$(x,y,y+h-1,c)$和$(x+w,y,y+h-1,-c)$,然后按照横坐标排序。关于纵坐标建立一颗线段树,维护区间最大值$dat$,初始全为$0$,线段树上的一个值$y$表示区间$[y,y+1]$,注意扫描每个四元组$(x,y_1,y_2,c)$,执行区间修改,把$[y1,y2]$中的每一个数都加$c$,用根节点$dat$更新就好了。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using std::min; using std::max;
using std::swap; using std::sort;
using std::unique; using std::lower_bound;
typedef long long ll;
#define int ll template<typename T>
void read(T &x) {
int flag = 1; x = 0; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
} const int N = 2e4 + 10;
ll n, W, H;
ll cf[N << 1], tot;
struct star { ll x, y, h; } s[N];
struct raw { ll x, y1, y2, d; } cy[N << 1]; int cnt;
inline bool cmp (const raw &a ,const raw &b) { return a.x < b.x || (a.x == b.x && a.d < b.d); }
ll val[N << 4], add[N << 4]; void pushdown(int o, int lc, int rc) {
if(add[o]) {
add[lc] += add[o], add[rc] += add[o];
val[lc] += add[o], val[rc] += add[o], add[o] = 0;
}
} void modify (int ml, int mr, ll k, int o = 1, int l = 1, int r = tot) {
if(l >= ml && r <= mr) { val[o] += k, add[o] += k; return ; }
int mid = (l + r) >> 1, lc = o << 1, rc = lc | 1;
pushdown(o, lc, rc);
if(ml <= mid) modify(ml, mr, k, lc, l, mid);
if(mr > mid) modify(ml, mr, k, rc, mid + 1, r);
val[o] = max(val[lc], val[rc]);
} signed main () {
while(scanf("%lld%lld%lld", &n, &W, &H) != EOF) {
cnt = tot = 0; ll ans = 0;
for(int i = 1; i <= n; ++i) {
read(s[i].x), read(s[i].y), read(s[i].h);
cy[++cnt] = (raw){s[i].x, s[i].y, s[i].y + H - 1, s[i].h};
cy[++cnt] = (raw){s[i].x + W, s[i].y, s[i].y + H - 1, -s[i].h};
cf[++tot] = s[i].y, cf[++tot] = s[i].y + H - 1;
} sort(&cf[1], &cf[tot + 1]), tot = unique(&cf[1], &cf[tot + 1]) - cf - 1;
sort(&cy[1], &cy[cnt + 1], cmp);
memset(val, 0, sizeof val), memset(add, 0, sizeof add);
for(int i = 1; i <= cnt; ++i) {
cy[i].y1 = lower_bound(&cf[1], &cf[tot + 1], cy[i].y1) - cf;
cy[i].y2 = lower_bound(&cf[1], &cf[tot + 1], cy[i].y2) - cf;
modify(cy[i].y1, cy[i].y2, cy[i].d);
ans = max(ans, val[1]);
}
printf("%lld\n", ans);
}
return 0;
}

Poj2482 Stars in Your Window(扫描线)的更多相关文章

  1. POJ2482 Stars in Your Window(扫描线+区间最大+区间更新)

    Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I stil ...

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

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

  3. POJ2482 Stars in Your Window 和 test20180919 区间最大值

    Stars in Your Window Language:Default Stars in Your Window Time Limit: 1000MS Memory Limit: 65536K T ...

  4. POJ2482 Stars in Your Window 题解

    Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I stil ...

  5. poj2482 Stars in Your Window

    此题可用线段树或静态二叉树来做. 考虑用线段树: 很容易想到先限定矩形横轴范围再考虑在此纵轴上矩形内物品总价值的最大值. 那么枚举矩形横轴的复杂度是O(n)的,考虑如何快速获取纵轴上的最大值. 我们不 ...

  6. 【POJ-2482】Stars in your window 线段树 + 扫描线

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

  7. 【POJ2482】Stars in Your Window

    [POJ2482]Stars in Your Window 题面 vjudge 题解 第一眼还真没发现这题居然™是个扫描线 令点的坐标为\((x,y)\)权值为\(c\),则 若这个点能对结果有\(c ...

  8. 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 ...

  9. 【POJ2482】【线段树】Stars in Your Window

    Description Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw ...

随机推荐

  1. [洛谷P1822] 魔法指纹

    洛谷题目连接:魔法指纹 题目描述 对于任意一个至少两位的正整数n,按如下方式定义magic(n):将n按十进制顺序写下来,依次对相邻两个数写下差的绝对值.这样,得到了一个新数,去掉前导0,则定义为ma ...

  2. 调戏OpenShift:一个免费能干的云平台(已失效)

    一.前因后果 以前为了搞微信的公众号,在新浪sae那里申请了一个服务器,一开始还挺好的 ,有免费的云豆送,但是一直运行应用也要消费云豆,搞得云豆也所剩无几了.作为一名屌丝,日常吃土,就单纯想玩一玩微信 ...

  3. luaj luaoc 回调函数传递的一些小总结

    问题场景:我们的游戏在支付时,由于第三方支付比较费时,可能在支付的过程中,我们lua写的cocos2dx项目会断网,我们的游戏有自动重连的机制.我就想,如果断线好了以后,支付完成了,那在断网之前传入的 ...

  4. O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素(转)

    题目要求:定义栈的数据结构,添加min().max()函数(动态获取当前状态栈中的最小元素.最大元素),要求push().pop().min().max()的时间复杂度都是O(1). 思路解析:根据栈 ...

  5. Java中通过方法创建一个http连接并请求(服务器间进行通信)

    服务器间进行通信只能通过流(Stream)的方式进行,不能用方法的返回值. 1.Java代码创建一个连接并请求该连接返回的数据 doGet()方法,execute()方法中调用 package dem ...

  6. 查看服务器是否被DDOS攻击的方法

    伴随着现代互联网络快速发展,更加容易出现被攻击.尤其是ddos攻击已经不在是大网站需要关心的事情了.不少中小型企业,也在遭受ddos攻击.站长对ddos攻击不了解,所以网站被ddos攻击的时候,都不会 ...

  7. [Leetcode Week12]Unique Paths II

    Unique Paths II 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/unique-paths-ii/description/ Descrip ...

  8. thread_info&内核栈

    转载:http://blog.chinaunix.net/uid-22548820-id-2125152.html 之所以将thread_info结构称之为小型的进程描述符,是因为在这个结构中并没有直 ...

  9. Linux 入门记录:四、Linux 系统常用命令

    一.日期时间 命令 date 查看.设置当前系统时间: date -u 格林威治时间 date %Y-%m-%d 显示格式化的时间 date -s "23:00" 使用 -s 参数 ...

  10. python基础===Excel处理库openpyxl

    openpyxl是一个第三方库,可以处理xlsx格式的Excel文件. 安装: pip install openpyxl 对如下excel进行读取操作,如图: from openpyxl import ...