题目链接:点我啊╭(╯^╰)╮
题目大意:
二维平面上有 n n n 个点,权值有正有负
选取一个正方形,里面的点全选
求最大点值和
解题思路:
坐标离散化之后枚举上下界
枚举的时候就将那一行的点 u p d a t e update update 到线段树里
然后维护最大字段和即可
还是很好写的。。。
那么问题又来了:线段树前加inline
,是不是就变成了非递归呢?
核心:线段树维护最大子段和
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
const int maxn = 2e4 + 5;
int cas, n;
struct node{int x, y, w, lsy;
} a[maxn];
vector <int> vx, vy;
vector <node> X[maxn];
ll tl[maxn<<1], tr[maxn<<1];
ll t[maxn<<1], T[maxn<<1];inline void pushup(int rt){tl[rt] = max(tl[rt<<1], t[rt<<1] + tl[rt<<1|1]);tr[rt] = max(tr[rt<<1|1], tr[rt<<1] + t[rt<<1|1]);t[rt] = t[rt<<1] + t[rt<<1|1];T[rt] = max(max(T[rt<<1], T[rt<<1|1]), tr[rt<<1] + tl[rt<<1|1]);
} inline void build(int l, int r, int rt){tl[rt] = tr[rt] = t[rt] = T[rt] = 0;if(l == r) return;int m = l + r >> 1;build(l, m, rt<<1);build(m+1, r, rt<<1|1);
}inline void update(int l, int r, int rt, int p, int w){if(l>p || r<p) return;if(l == r){tl[rt] += w, tr[rt] += w;t[rt] += w, T[rt] += w;return;}int m = l + r >> 1;update(l, m, rt<<1, p, w);update(m+1, r, rt<<1|1, p, w);pushup(rt);
}int main() {scanf("%d", &cas);while(cas--){scanf("%d", &n);vx.clear(), vy.clear();for(int i=0; i<=n; i++) X[i].clear();for(int i=1; i<=n; i++){int x, y, w;scanf("%d%d%d", &x, &y, &w);a[i].x = x, a[i].y = y, a[i].w = w;vx.push_back(x), vy.push_back(y);}sort(vx.begin(), vx.end());sort(vy.begin(), vy.end());vx.erase(unique(vx.begin(), vx.end()), vx.end());vy.erase(unique(vy.begin(), vy.end()), vy.end());for(int i=1; i<=n; i++) {int p = lower_bound(vx.begin(), vx.end(), a[i].x) - vx.begin();a[i].lsy = lower_bound(vy.begin(), vy.end(), a[i].y) - vy.begin();X[p].push_back(a[i]);}int N = vx.size();ll ans = 0;for(int up=0; up<N; up++){build(1, n, 1);for(int dw=up; dw<N; dw++){for(int i=0; i<X[dw].size(); i++)update(1, n, 1, X[dw][i].lsy+1, X[dw][i].w);ans = max(ans, T[1]);}}printf("%lld\n", ans);}
}