离散后用线段树维护最大子段和
枚举上界遍历下界更新答案
时间复杂度
代码:
/*
Zeolim - An AC a day keeps the bug away
*/
//pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define mp(x, y) make_pair(x, y)
#define fr(x, z, y) for(int x = z; x < y; ++x)
typedef long long ll;
typedef double ld;
typedef std::pair<int, int> pii;
typedef std::vector <short> vi;
//typedef __int128 ill;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const ll INF = 1e18;
const ll MOD = 1e9 + 7;
const int MAXN = 1e6 + 100;
ll n, m;
struct node
{
ll l, r;
ll val;
ll sum, lmax, rmax;
}tr[MAXN * 4];
void push(node &now, node &ls, node &rs)
{
now.sum = ls.sum + rs.sum;
now.lmax = max(ls.lmax, ls.sum + rs.lmax);
now.rmax = max(rs.rmax, rs.sum + ls.rmax);
now.val = max(ls.val, max( rs.val, ls.rmax + rs.lmax) );
}
void build(ll now, ll l, ll r)
{
tr[now].l = l, tr[now].r = r;
ll mid = (l + r) / 2;
if(l == r) {tr[now].val = tr[now].sum = tr[now].lmax = tr[now].rmax = 0; return;}
build(now * 2, l, mid);
build(now * 2 + 1, mid + 1, r);
push(tr[now], tr[now * 2], tr[now * 2 + 1]);
}
void change(ll now, ll p, ll v)
{
if(tr[now].l == tr[now].r) { tr[now].val = tr[now].sum = tr[now].lmax = tr[now].rmax = (tr[now].val + v); return;}
ll mid = (tr[now].l + tr[now].r) / 2;
if(p <= mid) change(now * 2, p, v);
if(p > mid) change(now * 2 + 1, p, v);
push(tr[now], tr[now * 2], tr[now * 2 + 1]);
}
node ask(ll now, ll l, ll r)
{
if(l <= tr[now].l && r >= tr[now].r) return tr[now];
ll mid = (tr[now].l + tr[now].r) / 2;
if(r <= mid) return ask(now * 2, l, r);
if(l > mid) return ask(now * 2 + 1, l, r);
node ls = ask(now * 2, l, r), rs = ask(now * 2 + 1, l, r), ans;
push(ans, ls, rs);
return ans;
}
struct rec
{
ll x, y, val;
}R[MAXN], arr[MAXN];
bool cmp(rec a, rec b)
{
return a.x < b.x;
}
ll vx[MAXN] = {0}, xf = 0;
ll vy[MAXN] = {0}, yf = 0;
ll retx(ll x) { return lower_bound(vx, vx + xf, x) - vx + 1; }
ll rety(ll x) { return lower_bound(vy, vy + yf, x) - vy + 1; }
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
//freopen("d:out.txt","w",stdout);
//freopen("d:in.txt","r",stdin);
ll t;
cin >> t;
while(t--)
{
xf = yf = 0;
cin >> n;
fr(i, 0, n)
{
cin >> R[i].x >> R[i].y >> R[i].val;
vx[xf++] = R[i].x;
vy[yf++] = R[i].y;
}
sort(vx, vx + xf);
xf = unique(vx, vx + xf) - vx;
sort(vy, vy + yf);
yf = unique(vy, vy + yf) - vy;
fr(i, 0, n)
{
arr[i + 1].x = retx(R[i].x);
arr[i + 1].y = rety(R[i].y);
arr[i + 1].val = R[i].val;
}
sort(arr + 1, arr + n + 1, cmp);
ll ans = 0;
for(ll i = 1; i <= n; ++i)
{
if(arr[i].x != arr[i - 1].x)
{
build(1, 1, yf);
for(int j = i; j <= n; ++j)
{
if(j != i && arr[j].x != arr[j - 1].x)
ans = max(ans, tr[1].val);
change(1, arr[j].y, arr[j].val);
}
ans = max(ans, tr[1].val);
}
}
cout << ans << '
';
}
return 0;
}
/*
2
4
1 1 50
2 1 50
1 2 50
2 2 -500
2
-1 1 5
-1 1 1
*/
/*
1
2
-1 1 5
-1 1 1*/