在一个 M∗M M ∗ M 的正方形平面中,给出 N N 个宝石的坐标 (xi,yi) ( x i , y i ) ,每个宝石的价值为 Ai A i ,有一块 K∗K K ∗ K 的布,问能覆盖的宝石的最大价值和是多少,宝石在布的边缘也算。
1≤m≤50000,1≤n≤50000,1≤k≤10000 1 ≤ m ≤ 50000 , 1 ≤ n ≤ 50000 , 1 ≤ k ≤ 10000
https://blog.csdn.net/gx_man_vip/article/details/80833641
跟这题比较类似,不过注意一下,边缘能够覆盖,所以右边缘不需要 −1 − 1 ,
然后每个矩形的上面的扫描线的纵坐标 y2 y 2 ,要变成 y2+1 y 2 + 1 ,因为边缘需要,所以在 y2+1 y 2 + 1 维护而不能在 y2 y 2 时维护
#include
#include
#include
#include
#include
#define N 500005
using namespace std;
struct Node {
int l, r, h, add;
}c[N];
struct Note {
int Lzy, Max;
int l, r;
}a[5 * N];
int x[N];
bool cmp(Node aa, Node bb) {
if (aa.h != bb.h) return aa.h < bb.h;
return aa.add < bb.add;
}
void Build_tree(int G, int l, int r) {
a[G].l = l, a[G].r = r;
a[G].Max = a[G].Lzy = 0;
if (l == r) return;
int mid = (l + r) >> 1;
Build_tree(G * 2, l, mid);
Build_tree(G * 2 + 1, mid + 1, r);
}
int Get_id(int num, int l, int r) {
while (l <= r) {
int mid = (l + r) >> 1;
if (x[mid] == num) return mid;
if (x[mid] < num) l = mid + 1;
else r = mid - 1;
}
return l;
}
double Get_max(int G) {
return max(a[G * 2].Max, a[G * 2 + 1].Max);
}
void Insert_tree(int G, int x1, int x2, int add) {
if (a[G].l == x1 && a[G].r == x2) {
a[G].Lzy += add;
a[G].Max += add;
return;
}
a[G * 2].Lzy += a[G].Lzy, a[G * 2].Max += a[G].Lzy;
a[G * 2 + 1].Lzy += a[G].Lzy, a[G * 2 + 1].Max += a[G].Lzy;
a[G].Lzy = 0;
int mid = (a[G].l + a[G].r) >> 1;
if (x2 <= mid) Insert_tree(G * 2, x1, x2, add);
else if (x1 > mid) Insert_tree(G * 2 + 1, x1, x2, add);
else {
Insert_tree(G * 2, x1, mid, add);
Insert_tree(G * 2 + 1, mid + 1, x2, add);
}
a[G].Max = Get_max(G);
}
int main() {
int x1, y1, z1, ans;
int tot = 0, m, n, k;
scanf("%d %d %d", &m, &n, &k);
for (int i = 1; i <= n; i++) {
scanf("%d %d %d", &x1, &y1, &z1);
x[++tot] = x1,
c[tot].l = x1, c[tot].r = min(x1 + k, m),
c[tot].h = y1, c[tot].add = z1;
x[++tot] = min(x1 + k, m),
c[tot].l = x1, c[tot].r = min(x1 + k, m),
c[tot].h = min(y1 + k + 1, m + 1), c[tot].add = -z1;
}
sort(c + 1, c + tot + 1, cmp);
sort(x + 1, x + tot + 1);
int cnt = 1;
for (int i = 2; i <= tot; i++)
if (x[i] != x[i - 1]) x[++cnt] = x[i];
ans = 0;
Build_tree(1, 1, cnt);
for (int i = 1; i <= tot; i++) {
int x1 = Get_id(c[i].l, 1, cnt);
int x2 = Get_id(c[i].r, 1, cnt);
if (x1 <= x2) Insert_tree(1, x1, x2, c[i].add);
ans = max(ans, a[1].Max);
}
printf("%d\n", ans);
return 0;
}