第一道扫描线+线段树题。

这道题还耗了我很久的时间,因为不懂得扫描线到底要怎么做而一直翻了很多dalao的题解。

这道题求的是一个指定大小的矩形可以框住多少颗星星,他们的亮度总和最大。

直接移动矩形不可行,我们将每颗星星转换为每颗星星能被矩形框住的响应区域,不难发现也是矩形。

为了不重复计算,我们只考虑在右上区域框住星星,不然会算重。

所以问题成功转换为:求最大的矩形的交,使相应面积最大。

这个时候就可以使用扫描线了。

可以从下往上扫描,每一次记录一个矩形的下边,加入一条线,加上附带的信息比如左右端点和更新答案值。

如何有顺序地扫描?直接用排序排一下就可以了。

思想很容易懂,但是如何使用代码实现?

我们使用一个结构体名字叫line,记录y轴,左右端点和对答案的贡献。

显然碰到矩形的下边,我们对答案就要区间加了,而碰到上边就要区间减了。

最后还要维护全局的最大值,可以直接写一个线段树模板化地维护。

然后还出了个锅:初始化全局任何元素都是0!连build都不用!

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn = 100005;
const int INF = 0x3f3f3f3f;
struct Line
{int l, r, y, val;
} line[maxn];
int ls[maxn];
int a[maxn], tot;
int n, w, h, ans;
struct segTree
{int maxv[maxn << 2], lazy[maxn << 2];#define lson (root << 1)#define rson (root << 1 | 1)void clear(){memset(maxv, 0, sizeof maxv);memset(lazy, 0, sizeof lazy);}void pushup(int root){maxv[root] = std::max(maxv[lson], maxv[rson]);}/*void build(int root, int l, int r){if(l == r) maxv[root] = a[l];else{int mid = (l + r) >> 1;build(lson, l, mid);build(rson, mid + 1, r);pushup(root);}}*/void pushdown(int root, int l, int r){if(lazy[root] != 0){int &x = lazy[root];maxv[lson] += x;lazy[lson] += x;maxv[rson] += x;lazy[rson] += x;x = 0;}}void update(int root, int l, int r, int x, int y, int k){if(r < x || y < l) return;if(x <= l && r <= y){maxv[root] += k;lazy[root] += k;return;}pushdown(root, l, r);int mid = (l + r) >> 1;update(lson, l, mid, x, y, k);update(rson, mid + 1, r, x, y, k);pushup(root);}int query(int root, int l, int r, int x, int y){if(r < x || y < l) return -INF;if(x <= l && r <= y) return maxv[root];pushdown(root, l, r);int mid = (l + r) >> 1;return std::max(query(lson, l, mid, x, y), query(rson, mid + 1, r, x, y));}
} seg;bool cmp(Line a, Line b)
{if(a.y == b.y) return a.val > b.val;return a.y < b.y;
}
int read()
{int ans = 0, s = 1;char ch = getchar();while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }while(ch >= '0' && ch <= '9') ans = (ans << 3) + (ans << 1) + ch - '0', ch = getchar();return s * ans;
}
void init()
{seg.clear();memset(line, 0, sizeof line);memset(ls, 0, sizeof ls);memset(a, 0, sizeof a);tot = 0;ans = -INF;
}
int main()
{int T = read();while(T--){init();n = read(), w = read(), h = read();for(int i = 1; i <= n; i++){int x = read(), y = read(), bright = read();ls[i] = x; ls[i + n] = x + w - 1;line[i].l = line[i + n].l = x;line[i].r = line[i + n].r = x + w - 1;line[i].val = bright; line[i + n].val = -bright;line[i].y = y; line[i + n].y = y + h - 1;}std::sort(ls + 1, ls + n + n + 1);a[++tot] = ls[1];for(int i = 2; i <= n + n; i++){if(ls[i] != ls[i - 1]) a[++tot] = ls[i];}std::sort(line + 1, line + n + n + 1, cmp);//seg.build(1, 1, tot);for(int i = 1; i <= n + n; i++){int l = std::lower_bound(a + 1, a + tot + 1, line[i].l) - a;int r = std::lower_bound(a + 1, a + tot + 1, line[i].r) - a;seg.update(1, 1, tot, l, r, line[i].val);//printf("%d\n", seg.maxv[1]);ans = std::max(ans, seg.maxv[1]);}printf("%d\n", ans);}return 0;
}

转载于:https://www.cnblogs.com/Garen-Wang/p/9815873.html

P1502 窗口的星星相关推荐

  1. P1502 窗口的星星(扫描线入门第一题)

    题目链接:https://www.luogu.org/problem/P1502 P1502 窗口的星星 提交2.78k 通过682 时间限制1.00s 内存限制125.00MB 提交代码加入收藏 题 ...

  2. P1502 窗口的星星 离散化+扫描线

    题意: 一个二维平面上有些点有权值. 问给你一个H*W的窗口,问窗口星星亮度总和的最大值. H∗W范围:1e6H*W 范围:1e6H∗W范围:1e6 坐标范围:1e9坐标范围:1e9坐标范围:1e9 ...

  3. Luogu P1502 窗口的星星 (扫描线)

    Description 晚上,小卡从阳台望出去,"哇~~~~好多星星啊",但他还没给其他房间设一个窗户. 天真的小卡总是希望能够在晚上能看到最多最亮的星星,但是窗子的大小是固定的, ...

  4. P1502 窗口的星星题解(扫描线)

    知识点:线段树+扫描线 看了看这道题的x,y的数据范围,固定离散化. 注意避坑,方框上的不算. 题目的大致意思是给若干个点,然后给个方框求怎么框才能框柱尽可能多的星星. 我们要使用扫描线的时候通常是求 ...

  5. 题解报告——窗口的星星

    题目背景 小卡买到了一套新房子,他十分的高兴,在房间里转来转去. 题目描述 晚上,小卡从阳台望出去,"哇~~~~好多星星啊",但他还没给其他房间设一个窗户,天真的小卡总是希望能够在 ...

  6. 【数据结构2-2】线段树与树状数组 题解

    头一次老老实实写完一个官方题单,发篇题解纪念一下-- 文章目录 P3372 [模板]线段树 1 P3373 [模板]线段树 2 P4588 [TJOI2018]数学计算 P1502 窗口的星星 P24 ...

  7. (详细)星空动态特效(基于C语言+EasyX库实现)

    1.程序运行环境(必读)                      Visual C++ 6.0.Visual Studio 2010 ~ Visual Studio 2022 等支持EasyX图形库 ...

  8. java花星星 星星大小随机_java 在窗口中用*号,随机画星星和满月

    展开全部 import java.awt.Graphics; import java.awt.Color; import java.awt.event.WindowAdapter; import ja ...

  9. [问题处理]redmine的gantt图导出出现‘星星星星星星星星’怎么解决

      问题描述: redmine中的gantt图用途还是非常大,对于使用习惯了ms project的人来说,必不可少的一个东西,但是gantt图在导出到PDF时候,会出现'星星星星星星星星'问题,很是不 ...

最新文章

  1. 鸿蒙系统合适上线手机端,华为官方:鸿蒙系统2.0上线,手机能否搭载鸿蒙操作系统?...
  2. GTS解密--GTS的原理、架构与特点
  3. “静态常量”与“ #define”与“枚举”
  4. 产品经理必备知识之网页设计系列(三)-移动端适配无障碍设计及测试
  5. caffe安装,编译(包括CUDA和cuDNN的安装),并训练,测试自己的数据(caffe使用教程)
  6. Linux日志出现大量kernel: NET: Registered protocol family 36
  7. Java-Redis 热部署问题
  8. 聚焦四大领域,恒生电子发布2022年金融科技技术与应用趋势
  9. vmware workstation克隆linux后修改网卡为eth0方法
  10. arm平台下linux c语言编程,简单分析针对ARM平台的C语言程序的编译问题
  11. PPP协议的配置(以H3C模拟器为例)
  12. javascript实现一行文字随不同设备自适应改变字体大小至字数完全展示
  13. PHP用户连续签到赠送额外积分
  14. C#Excel上传批量导入sqlserver
  15. python数据类型有哪些、分别有什么用途_python数据类型
  16. 尺规画图——三等分点
  17. 估值择时对ETF基金定投的影响
  18. JDK8升至JDK11 新特性整理
  19. 算例在线帮 | 某型无厚度翅片水冷板散热的Fluent仿真分析
  20. lt;html xmlns=http://www.w3.org/1999/xhtmlgt;

热门文章

  1. js 正则匹配特殊字符
  2. C-输入句子,逆语序输出
  3. web服务器性能指标有哪些,web服务器性能指标
  4. 大数据到底怎么学: 数据科学概论与大数据学习误区
  5. excel如何快速选择一列数据
  6. linux yum卸载与安装软件包,Linux yum命令详解(查询、安装、升级和卸载软件包)...
  7. Linux虚拟机修改主机名
  8. Python 内置函数isdigit()
  9. JSTL的jar包问题
  10. PVA-MVSNet