运用扫描线的方法,每一次都用一个大小固定的小矩形去框住星星,大致过程如图所示

我们要求出小矩形最多可以框住多少颗星星,也就是求出来这个区间的最大值是多少,因为小矩形的移动过程中要维护区间最大值,所以我们可以选择用线段树去维护区间最大值,我们按照星星的纵坐标去建树,并且我们要对星星按照它的横坐标从小到大排序,这样我们只需要离散化纵坐标之后,就可以按照它们的横坐标从左往右扫一遍。求区间中星星的亮度我们可以采用差分的思考方式,给这个区间的左边界(即以x为横坐标所对应的y,y+h这一条边)加上它的亮度,在右边界减去它的亮度。这样我们就可以求出来区间的值是多少。
因为涉及到了区间加法,所以我们要用懒惰标记去维护区间要加的值是多少。
#include <bits/stdc++.h>
using i64 = long long;
#define rep(i, a, n) for (int i = a; i < n; i ++ )
#define per(i, a, n) for (int i = n - 1; i >= a; i -- )
#define SZ(a) (int(a.size()))
#define pb push_back
#define all(a) a.begin(), a.end()
constexpr int N = 10010;
struct Seg {
int l, r;
i64 val, tag;
}tr[N << 3];
struct Star {
int x, y1, y2;
i64 w;
bool operator< (const Star& W) const {
if (x == W.x) return w < W.w;
return x < W.x;
}
}seg[N << 2];
void pushup(int u) {
tr[u].val = std::max(tr[u << 1].val, tr[u << 1 | 1].val) + tr[u].tag;
}
void build(int u, int l, int r) {
tr[u] = {l, r, 0, 0};
if (l == r) return ;
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void modify(int u, int l, int r, i64 val) {
if (tr[u].l >= l && tr[u].r <= r) {
tr[u].val += val;
tr[u].tag += val;
return ;
}
int mid = (tr[u].l + tr[u].r) >> 1;
if (mid >= l) modify(u << 1, l, r, val);
if (mid < r) modify(u << 1 | 1, l, r, val);
pushup(u);
}
void solve() {
int n, w, h; scanf("%d%d%d", &n, &w, &h);
std::vector<int> ys;
for (int i = 1, j = 0; i <= n; i ++ ) {
int x, y;
i64 val;
scanf("%d%d%lld", &x, &y, &val);
seg[j ++ ] = {x, y, y + h, val};
seg[j ++ ] = {x + w, y, y + h, -val};
ys.pb(y), ys.pb(y + h);
}
std::sort(ys.begin(), ys.end());
ys.erase(std::unique(ys.begin(), ys.end()), ys.end());
build(1, 0, int(ys.size()) - 1);
std::sort(seg, seg + 2 * n);
i64 ans = 0;
auto find = [&] (int x) -> int {
return std::lower_bound(ys.begin(), ys.end(), x) - ys.begin();
};
for (int i = 0; i < n * 2; i ++ ) {
modify(1, find(seg[i].y1), find(seg[i].y2) - 1, seg[i].w);
ans = std::max(ans, tr[1].val);
}
printf("%lld\n", ans);
}
int main() {
int t; scanf("%d", &t);
while (t -- ) solve();
return 0;
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现