题解看这位大佬,讲的很详细了。
反思:
- 本题做的时候,已经想到二维子段和了,但不知怎么维护。
- 看了题解,原来要用线段树,之后暴力算答案。
- 先只看纵坐标,即只看y时(即一条水平的扫描线时),那么先暴力枚举所有可能的矩形(这些
矩形,只知道上下界,左右边界还是未知的
) - 对于每一次枚举y上界时(即一条水平的扫描线时),可以看一下这条水平扫描线y上是否有点,有就加入到【1,cntx】的线段树里,根据x坐标,往区间里进行点修改(由于数据坐标有1e9,所以要先离线做哦( ̄▽ ̄)")
每次遇到 上界y 上的点都维护一下【1,cntx】。
- 上面讲到的线段树只维护【1,cntx】。每次y的下界确定时。枚举y上界。(由于每一次变动上界y,都是一个新矩形,所以更新下答案即可)
- 总复杂度
n
2
l
o
g
n
n^2logn
n2logn
AC
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mst(x,a) memset(x,a,sizeof(x))
#define lc u<<1
#define rc u<<1|1
using namespace std;
typedef long long ll;
const int maxn=2e3+10;
struct point {
int x,y;
ll val;
bool operator<(const point&p)const{
return y<p.y||(y==p.y&&x<p.x);
}
}p[maxn];
struct node{
ll sum,pre,mx,suf;
}tree[maxn<<2];
void clean(int u, int l ,int r){
tree[u].sum=tree[u].mx=tree[u].pre=tree[u].suf=0;
if(l==r)return ;
int mid=(l+r)>>1;
clean(lc,l,mid);
clean(rc,mid+1,r);
}
void pushup(int u){
tree[u].sum=tree[lc].sum+tree[rc].sum;
tree[u].mx=max(max(tree[lc].mx,tree[rc].mx),tree[lc].suf+tree[rc].pre);
tree[u].pre=max(tree[lc].pre,tree[lc].sum+tree[rc].pre);
tree[u].suf=max(tree[rc].suf,tree[rc].sum+tree[lc].suf);
}
void modify(int u, int l, int r, int x, ll val){
if(l==r){
tree[u].mx=tree[u].pre=tree[u].suf=(tree[u].sum+=val);
return ;
}
int mid=(l+r)>>1;
if(x<=mid)modify(lc,l,mid,x,val);
else modify(rc,mid+1,r,x,val);
pushup(u);
}
int n;
int lx[maxn],ly[maxn];
int cntx,cnty;
void init(){
cntx=cnty=0;
scanf("%d", &n);
for(int i=1; i<=n; i++){
scanf("%d%d%lld",&p[i].x,&p[i].y,&p[i].val);
lx[++cntx]=p[i].x;
ly[++cnty]=p[i].y;
}
sort(p+1,p+1+n);
sort(lx+1,lx+1+cntx);sort(ly+1,ly+1+cnty);
cntx=unique(lx+1,lx+1+cntx)-lx-1;cnty=unique(ly+1,ly+1+cnty)-ly-1;
for(int i=1; i<=n; i++){
p[i].x=lower_bound(lx+1,lx+1+cntx,p[i].x)-lx;
p[i].y=lower_bound(ly+1,ly+1+cnty,p[i].y)-ly;
}
}
int main()
{
int t;scanf("%d", &t);
while(t--){
init();
ll ans=0;
int pos=1;
for(int i=1; i<=cnty; i++){
clean(1,1,cntx);
for(int j=i,k=pos; j<=cnty; j++){
while(k<=n&&j==p[k].y){
modify(1,1,cntx,p[k].x,p[k].val);
k++;
}
if(j==i)pos=k;
ans=max(ans,tree[1].mx);
}
}
printf("%lld\n",ans);
}
return 0;
}