#include <iostream>
#include <stdio.h>
#include <bits/stdc++.h>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define inf 0x1fffffff
#define maxn 20007
#define LL long long
using namespace std;
//SBT 离散化
LL Rank[maxn], Rn;
void SetRank() { //相当于unique
sort(Rank + 1, Rank + 1 + Rn);//先排序
int I = 1;
for (int i = 2; i <= Rn; ++i) if (Rank[i] != Rank[i - 1]) Rank[++I] = Rank[i];//不重复的放进去
Rn = I;
}
int GetRank(LL x) {
int L = 1, R = Rn, M;//[L,R] first >=x
while (L != R) {
M = (L + R) >> 1;
if (Rank[M] < x) L = M + 1;
else R = M;
}
return L;
}
//储存数据
struct Star {//记录星星,之后要排序
LL x, y; int c;
Star() {}
Star(LL x, LL y, int c) :x(x), y(y), c(c) {}
bool operator < (const Star& B)const {
return x < B.x || x == B.x && y < B.y;
}
}St[maxn >> 1];
int n, W, H;
//线段树 区间加&&最大值
int Max[maxn << 2], Add[maxn << 2];
void PushUp(int rt) {
Max[rt] = max(Max[rt << 1], Max[rt << 1 | 1]);
}
void PushDown(int rt) {
if (Add[rt]) {
Add[rt << 1] += Add[rt]; Add[rt << 1 | 1] += Add[rt];
Max[rt << 1] += Add[rt]; Max[rt << 1 | 1] += Add[rt];
Add[rt] = 0;
}
}
void Update(int L, int R, int C, int l, int r, int rt) {
if (L <= l && r <= R) { Add[rt] += C; Max[rt] += C; return; }
PushDown(rt);
int m = (l + r) >> 1;
if (L <= m) Update(L, R, C, l, m, rt << 1);
if (R > m) Update(L, R, C, m + 1, r, rt << 1 | 1);
PushUp(rt);
}
int main(void)
{
while (cin>>n>>W>>H)) {
memset(Max, 0, sizeof(Max));
memset(Add, 0, sizeof(Add));
Rn = 0;
for (int i = 1; i <= n; ++i) {
cin>>St[i].x>>St[i].y>>St[i].c;
Rank[++Rn] = St[i].y;
Rank[++Rn] = St[i].y + H; //存入纵坐标
}
SetRank();
sort(St + 1, St + n + 1);//给星星排序
int L = 1, X, ANS = 0;
for (int i = 1; i <= n; ++i) {
Update(GetRank(St[i].y), GetRank(St[i].y + H) - 1, St[i].c, 1, Rn, 1);//加入新矩形
X = St[i].x;//更新当前X 星星的横坐标
while (St[L].x + W <= X) {//删除已经对横坐标为X的扫描线无影响的矩形
Update(GetRank(St[L].y), GetRank(St[L].y + H) - 1, -St[L].c, 1, Rn, 1);
++L;
}
ANS = max(ANS, Max[1]);//求最大值
}
printf("%d\n", ANS);//输出答案
}
return 0;
}
线段树-poj2482矩形框星星
最新推荐文章于 2024-09-20 20:16:39 发布