在 y 轴上建立线段树进行维护最大值。
先加后减,一条线查询一次,所以我并没有让横坐标减 1,不知道哪里错了,求调。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e4+10;
int T , n , H , W;
ll a[N<<2] , idx;
struct Seg
{
ll x , y1 , y2 , val;
bool operator <(const Seg &o) const
{
if (x==o.x) return val>o.val;
return x<o.x;
}
}seg[N<<1];
struct node
{
int l , r;
ll mx , add;
}tr[N<<3];
ll res = 0;
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);
}
inline void init()
{
idx = 0ll;
res = -1e18;
}
inline void pushup (int u)
{
tr[u].mx = max(tr[u<<1].mx , tr[u<<1|1].mx);
}
inline void pushdown (int u)
{
if (tr[u].add)
{
tr[u<<1].add += tr[u].add , tr[u<<1|1].add += tr[u].add;
tr[u<<1].mx += tr[u].add , tr[u<<1|1].mx += tr[u].add;
tr[u].add = 0;
}
}
void modify (int u , int l , int r , int x)
{
if (l<=tr[u].l && tr[u].r<=r)
{
tr[u].mx += x , tr[u].add += x;
}
else
{
pushdown(u);
int mid = (tr[u].l+tr[u].r)>>1;
if (l<=mid)
{
modify(u<<1 , l , r , x);
}
if (r>mid)
{
modify(u<<1|1 , l , r , x);
}
pushup(u);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> T;
while(T--)
{
cin >> n >> H >> W;
init();
for (int i=1 ; i<=n ; i++)
{
int x , y , z;
cin >> x >> y >> z;
seg[(i-1)*2+1] = {x , y , y+H-1 , z};
seg[(i-1)*2+2] = {x+W , y , y+H-1 , -z};
a[++idx] = x , a[++idx] = x+W;
a[++idx] = y , a[++idx] = y+H-1;
}
sort(a+1 , a+1+idx);
int len_a = unique(a+1 , a+1+idx)-a;
for (int i=1 ; i<=2*n ; i++)
{
seg[i].x = lower_bound(a+1 , a+len_a , seg[i].x)-a;
seg[i].y1 = lower_bound(a+1 , a+len_a , seg[i].y1)-a;
seg[i].y2 = lower_bound(a+1 , a+len_a , seg[i].y2)-a;
}
build(1 , 1 , len_a);
sort(seg+1 , seg+1+n*2);
for (int i=1 ; i<=n*2 ; i++)
{
// while(seg[i].x==seg[i+1].x)
// {
// modify(1 , seg[i].y1 , seg[i].y2 , seg[i].val);
// i++;
// }
modify(1 , seg[i].y1 , seg[i].y2 , seg[i].val);
res = max(res , tr[1].mx);
}
cout << res << '\n';
}
return 0;
}
/*
2
3 5 4
1 2 3
2 3 2
6 3 1
3 5 4
1 2 3
2 3 2
5 3 1
*/