题目链接
线段树做法
代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 10010;
vector<int> row;
struct Line {
int x, y1, y2, v;
bool operator < (const Line& l) const {
return x == l.x ? v > l.v : x < l.x;
}
}line[N << 1];
struct Node {
int l, r, v, lz;
}tr[N << 3];
inline void eval(Node& t, int k) {
t.v += k;
t.lz += k;
}
inline void push_down(int u) {
eval(tr[u << 1], tr[u].lz);
eval(tr[u << 1 | 1], tr[u].lz);
tr[u].lz = 0;
}
void build(int u, int l, int r) {
tr[u] = { l , r , 0, 0};
if (l != r) {
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
}
}
void modify(int u, int l, int r, int k) {
if (l <= tr[u].l && r >= tr[u].r) eval(tr[u], k);
else {
push_down(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) modify(u << 1, l, r, k);
if (r > mid) modify(u << 1 | 1, l, r, k);
tr[u].v = tr[u << 1].v > tr[u << 1 | 1].v ? tr[u << 1].v : tr[u << 1 | 1].v;
}
}
int find(int k) {
int l = 0, r = row.size() - 1;
while (l < r) {
int mid = l + r >> 1;
if (k <= row[mid]) r = mid;
else l = mid + 1;
}
return l + 1;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n, w, h, ans = 0;
scanf("%d%d%d", &n, &w, &h);
for (int i = 0; i < n; ++i) {
int x, y, v;
scanf("%d%d%d", &x, &y, &v);
line[i << 1] = { x, y, y + h - 1, v };
line[i << 1 | 1] = { x + w - 1, y, y + h - 1, -v };
row.push_back(y);
row.push_back(y + h - 1);
}
sort(line, line + 2 * n);
sort(row.begin(), row.end());
row.erase(unique(row.begin(), row.end()), row.end());
build(1, 1, row.size());
for (int i = 0; i < 2 * n; ++i) {
modify(1, find(line[i].y1), find(line[i].y2), line[i].v);
ans = ans < tr[1].v ? tr[1].v : ans;
}
row.clear();
printf("%d\n", ans);
}
return 0;
}