#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct shu
{
int l,r;
ll w,lw,rw,ww;
}w[100000];
void up(int k,int l,int r)
{
int mid=(l+r)/2;
int lk=k<<1,rk=k<<1|1;
w[k].ww=max(max(w[lk].ww,w[rk].ww),w[lk].rw+w[rk].lw);
w[k].w=w[lk].w+w[rk].w;
if(w[lk].w+w[rk].lw>=w[lk].lw)
{
w[k].lw=w[lk].w+w[rk].lw;
w[k].l=w[rk].l;
}
else
{
w[k].l=w[lk].l;
w[k].lw=w[lk].lw;
}
if(w[rk].w+w[lk].rw>=w[rk].rw)
{
w[k].rw=w[rk].w+w[lk].rw;
w[k].r=w[lk].r;
}
else
{
w[k].r=w[rk].r;
w[k].rw=w[rk].rw;
}
}
void add(int k,int l,int r,int x,ll y)
{
if(l==r)
{
ll ww=w[k].w+y;
w[k]={l,l,ww,ww,ww,ww};
if(w[k].w<0) w[k].l=l-1,w[k].r=r+1,w[k].lw=w[k].rw=0,w[k].ww=0;
return;
}
int mid=(l+r)/2;
if(x<=mid) add(k<<1,l,mid,x,y);
else add(k<<1|1,mid+1,r,x,y);
up(k,l,r);
}
void build(int k,int l,int r)
{
if(l==r)
{
w[k]={l,r,0,0,0,0};
return;
}
int mid=(l+r)/2;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
up(k,l,r);
}
int n;
struct dian
{
int x,y;
ll w;
friend bool operator <(dian a,dian b)
{
return a.x<b.x;
}
}a[2005];
ll b[2005];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d%lld",&a[i].x,&a[i].y,&a[i].w);
b[i]=a[i].y;
}
sort(b+1,b+1+n);
int t=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++)
{
a[i].y=lower_bound(b+1,b+1+t,a[i].y)-b;
}
sort(a+1,a+1+n);
ll ans=0;
int jj;
for(int i=1;i<=n;i++) if(i==n||a[i].x!=a[i+1].x)
{
build(1,1,t);
for(int j=i;j>=1;)
{
jj=j;
while(j>=1&&a[j].x==a[jj].x)
{
add(1,1,t,a[j].y,a[j].w);
j--;
}
ans=max(ans,w[1].ww);
}
}
printf("%lld\n",ans);
}
return 0;
}
求区间内最大(最小)子区间的线段树
最新推荐文章于 2021-07-28 09:58:22 发布