题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6638
题意:在一个二维平面内给出n个点每个点有权值,要求画一个矩形使得这个矩形内的点的权值和最大。
数据范围:1≤T≤100,1≤n≤2000,−1e9≤xi,yi,wi≤1e9,∑n≤10000
思路:首先离散化,对于每次点数最多是2000个所以离散化后最大是一个2000*2000的地图这时候只需要找一个矩形内的权值和最大就行,所以我们可以用n*n去枚举上下界,对于每一个上下界建一棵线段树维护一下区间连续字段和最大即可。剩下就是模板的区间合并了,具体都写在update函数里了。
#include
#define ls (x<<1)
#define rs (x<<1|1)
using namespace std;
typedef long long ll;
const int N=2e3+10;
int n,m,t,xx[N],yy[N],val[N],idx[N],idy[N];
vectorG[N];
struct Tree{
ll sum,maxx,maxl,maxr;
}tree[N<<2];
void build(int x,int l,int r){
tree[x].maxx=tree[x].sum=tree[x].maxl=tree[x].maxr=0;
if(l==r)return ;
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
}
void update(int x,int l,int r,int pos,int val){
if(l==r){
tree[x].sum+=val;
tree[x].maxx=tree[x].maxl=tree[x].maxr=tree[x].sum;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid)update(ls,l,mid,pos,val);
if(pos>mid)update(rs,mid+1,r,pos,val);
tree[x].sum=tree[ls].sum+tree[rs].sum;
tree[x].maxl=max(tree[ls].maxl,tree[ls].sum+tree[rs].maxl);
tree[x].maxr=max(tree[rs].maxr,tree[rs].sum+tree[ls].maxr);
tree[x].maxx=max(max(tree[ls].maxx,tree[rs].maxx),tree[ls].maxr+tree[rs].maxl);
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++)G[i].clear();
for(int i=1;i<=n;i++){
scanf("%d%d%d",&xx[i],&yy[i],&val[i]);
idx[i]=xx[i],idy[i]=yy[i];
}
sort(xx+1,xx+n+1),sort(yy+1,yy+n+1);
for(int i=1;i<=n;i++){
idx[i]=lower_bound(xx+1,xx+n+1,idx[i])-xx;
idy[i]=lower_bound(yy+1,yy+n+1,idy[i])-yy;
G[idy[i]].push_back(i);
}
ll ans=0;
for(int i=1;i<=n;i++){
build(1,1,n);
for(int j=i;j<=n;j++){
int len=G[j].size();
for(int k=0;k