题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=6638

题目

Problem Description

There are n pirate chests buried in Byteland, labeled by 1,2,…,n. The i-th chest's location is (xi,yi), and its value is wi, wi can be negative since the pirate can add some poisonous gases into the chest. When you open the i-th pirate chest, you will get wi value.

You want to make money from these pirate chests. You can select a rectangle, the sides of which are all paralleled to the axes, and then all the chests inside it or on its border will be opened. Note that you must open all the chests within that range regardless of their values are positive or negative. But you can choose a rectangle with nothing in it to get a zero sum.

Please write a program to find the best rectangle with maximum total value.

Input

The first line of the input contains an integer T(1≤T≤100), denoting the number of test cases.

In each test case, there is one integer n(1≤n≤2000) in the first line, denoting the number of pirate chests.

For the next n lines, each line contains three integers xi,yi,wi(−1e9≤xi,yi,wi≤1e9), denoting each pirate chest.

It is guaranteed that ∑n≤10000.

Output

For each test case, print a single line containing an integer, denoting the maximum total value.

Sample Input

2

4

1 1 50

2 1 50

1 2 50

2 2 -500

2

-1 1 5

-1 1 1

Sample Output

100

6

思路

先离散化。再枚举矩阵的上下界。固定上界,枚举下界。

w1 w2 w3 w4
w5 w6 w7 w8
w9 w10 w11 w12

a[]=

w1+w5+w9 w2+w6+w10 w3+w7+w11 w4+w8+w12

如图,用一个序列a[]实时统计从当前上界到下界的元素之和。那么序列a[]的最大子段和就是当前上界下界的所有矩形中最大的权值和。序列a[]的最大子段和可用线段树维护。

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;const ll N=2010;
ll n,nx,ny;
struct node{ll x,y,ls,rs,s,ms;
};
node tree[N<<2];void init(){ll i;for(i=0;i<(N<<2);i++){tree[i].x=tree[i].y=tree[i].ls=tree[i].rs=tree[i].s=tree[i].ms=0;}
}struct nodes{ll x,y,w;
}p[N];bool cmp1(nodes u,nodes v){return u.x<v.x;
}bool cmp2(nodes u,nodes v){return u.y<v.y;
}bool cmp(nodes u,nodes v){if(u.x==v.x){return u.y<v.y;}else{return u.x<v.x;}
}ll d1[N],d2[N];
void discret(){ll i;sort(p+1,p+1+n,cmp1);        memset(d1,0,sizeof(d1));d1[1]=1;for(i=2;i<=n;i++){if(p[i].x==p[i-1].x)d1[i]=d1[i-1];else{d1[i]=d1[i-1]+1;}}for(i=1;i<=n;i++)p[i].x=d1[i];      memset(d2,0,sizeof(d2));d2[1]=1;   sort(p+1,p+1+n,cmp2);for(i=2;i<=n;i++){if(p[i].y==p[i-1].y)d2[i]=d2[i-1];else{d2[i]=d2[i-1]+1;}}for(i=1;i<=n;i++)p[i].y=d2[i];nx=d1[n];ny=d2[n];sort(p+1,p+1+n,cmp);
}void update(ll bh){tree[bh].ms=max(tree[bh<<1].ms,tree[(bh<<1)+1].ms);tree[bh].ms=max(tree[bh].ms,tree[bh<<1].rs+tree[(bh<<1)+1].ls);tree[bh].ls=max(tree[bh<<1].ls,tree[bh<<1].s+tree[(bh<<1)+1].ls);tree[bh].rs=max(tree[(bh<<1)+1].rs,tree[(bh<<1)+1].s+tree[bh<<1].rs);tree[bh].s=tree[bh<<1].s+tree[(bh<<1)+1].s;
}void build(ll bh,ll l,ll r){tree[bh].x=l; tree[bh].y=r;if (l==r){tree[bh].s=tree[bh].ms=tree[bh].ls=tree[bh].rs=0;return;}ll mid=(l+r)>>1;build(bh<<1,l,mid);build((bh<<1)+1,mid+1,r);update(bh);
}void change(ll bh,ll mb,ll z)
{if (tree[bh].x==tree[bh].y&&tree[bh].x==mb){tree[bh].s+=z;tree[bh].ms+=z;tree[bh].ls+=z;tree[bh].rs+=z;return;}ll mid=(tree[bh].x+tree[bh].y)>>1;if (mb<=mid) change(bh<<1,mb,z);else change((bh<<1)+1,mb,z);update(bh);
}ll askl(ll bh,ll l,ll r){if (tree[bh].x==l&&tree[bh].y==r) return tree[bh].ls;ll mid=(tree[bh].x+tree[bh].y)>>1;if (r<=mid) askl(bh<<1,l,r);else if (l>mid) askl((bh<<1)+1,l,r);ll lans=(bh<<1,l,mid); ll rans=((bh<<1)+1,mid+1,r); return max(lans,rans+tree[bh<<1].s);
}ll askr(ll bh,ll l,ll r){if (tree[bh].x==l&&tree[bh].y==r) return tree[bh].rs;ll mid=(tree[bh].x+tree[bh].y)>>1;if (r<=mid) askr(bh<<1,l,r);else if (l>mid) askr((bh<<1)+1,l,r);ll lans=askr(bh<<1,l,mid);ll rans=askr((bh<<1)+1,mid+1,r);  return max(rans,lans+tree[(bh<<1)+1].s);
}ll ask(ll bh,ll l,ll r){if (tree[bh].x==l&&tree[bh].y==r) return tree[bh].ms;ll mid=(tree[bh].x+tree[bh].y)>>1;if (r<=mid) ask(bh<<1,l,r);else if (l>mid) ask((bh<<1)+1,l,r);ll lans=ask(bh<<1,l,mid);ll rans=ask((bh<<1)+1,mid+1,r);ll ans=max(lans,rans);return max(ans,askr(bh<<1,l,mid)+askl((bh<<1)+1,mid+1,r));
}int main()
{ll i,j,k,T;scanf("%lld",&T);while(T--){ll ans=0;scanf("%lld",&n);for(i=1;i<=n;i++){scanf("%lld%lld%lld",&p[i].x,&p[i].y,&p[i].w);}   discret();for(i=1;i<=nx;i++){init();build(1,1,n);k=1;while(p[k].x<i)k++;for(j=i;j<=nx;j++){if(k>n)break;while(p[k].x==j){change(1,p[k].y,p[k].w);k++;if(k>n)break;}ans=max(ans,ask(1,1,n));   }}cout<<ans<<endl;}return 0;
}

hdu6638 Snowy Smile(线段树+最大子段和)相关推荐

  1. [SDOI2011]染色 (线段树维护子段问题+树剖)

    题意: 给定一棵 n 个节点的无根树,共有 m 个操作,操作分为两种: 1.将节点 a 到节点 b 的路径上的所有点(包括 a 和 b)都染成颜色 c. 2.询问节点 a 到节点 b 的路径上的颜色段 ...

  2. ACwing 245. 你能回答这些问题吗(线段树区间子段最大值+单点修改)

    给定长度为N的数列A,以及M条指令,每条指令可能是以下两种之一: 1."1 x y",查询区间 [x,y] 中的最大连续子段和,即 maxx≤l≤r≤ymaxx≤l≤r≤y{∑ri ...

  3. [2020-11-24 contest]糖果机器(二维偏序),手套(状压dp),甲虫(区间dp),选举(线段树 最大子段和)

    文章目录 T1:糖果机器 solution code T2:手套 solution code T3:甲虫 solution code T4:选举 solution code T1:糖果机器 solut ...

  4. codevs 3981 动态最大子段和(线段树)

    题目传送门:codevs 3981 动态最大子段和 题目描述 Description 题目还是简单一点好... 有n个数,a[1]到a[n]. 接下来q次查询,每次动态指定两个数l,r,求a[l]到a ...

  5. Can you answer these queries V SPOJ - GSS5 (分类讨论+线段树维护区间最大子段和)

    recursion有一个整数序列a[n].现在recursion有m次询问,每次她想知道Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 &l ...

  6. 线段树维护(最大区间和,最大子段和,最长连续上升子序列)

    本文主要介绍用线段树来维护(最大区间和,最大子段和,最长连续上升子序列)的问题. HDU 1540 Tunnel Warfare(最长连续区间+单点修改) 洛谷 P2894 [USACO08FEB]酒 ...

  7. Can you answer these queries III (线段树维护最大子段和)

    题意: 求一个区间的最大连续和. 0:表示把A[x]改成y 1:表示求[x,y]这个区间的最大连续和. 题解: 线段树维护四个变量. 倒着讲,先来看如何维护这四个变量. summax代表这个区间连续最 ...

  8. 子段乘积(逆元费马小定理)+线段树做法

    题解:一开始做这个题的时候想过尺取法,但是因为没有逆元的知识,不知道该如何不断删除左端元素.其实这题并不难想,设l,r为两端开始都置为1,当长度小于k的时候不断乘右端元素并取余,当长度等于k时删除左端 ...

  9. SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并

    Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目. 传送门: 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间 ...

  10. 可持久化普通线段树 ---- P2839 [国家集训队]middle 可持久化普通线段树 + 二分 求中位数最大值

    题目链接 题目大意: 解题思路: 这个题思路很妙!! 首先我们假设只有一次询问怎么做? 那么我们可以二分出这个最大值midmidmid,然后把大于等于midmidmid设置成111,把小于midmid ...

最新文章

  1. python怎么安装requests库-小白安装python的第三方库:requests库
  2. 4G内存服务器的MySQL配置优化
  3. 循环判定闰年的程序_C语言入门教程(六)for循环
  4. 如何安装使用MQCache缓存服务器(适用X300型或者X500型)
  5. win7远程连接开启方法
  6. PAT 乙级 1054. 求平均值 (20) Java版
  7. jvisualvm/Jconsole监控WAS(WebSphere)中间件
  8. JAVA日志框架概述
  9. LINUX安装之后,图标显示问题
  10. 怎么用python画sin函数图像_用python画三角函数
  11. 《计算机组成与设计(ARM版)》读书笔记-第二章指令1
  12. python抓取彩票数据_编写python爬虫采集彩票网站数据,将数据写入mongodb数据库...
  13. Android开发之麦田福音网移动版本演示程序
  14. python中text格式_python读取各种格式的文本
  15. Java实现数据库新增修改防止编码重复功能
  16. centos:centos7.3镜像下载
  17. 爬取起点中文网小说介绍信息
  18. 计算机CAD技术在工程设计中的应用,研究在机械工程设计中CAD技术的运用
  19. 1603: 海岛争霸
  20. android蓝牙开源,开源蓝牙框架 Android-BLE

热门文章

  1. axure中图表背影_Axure教程:如何制作可视化图表?
  2. python 通信中间件_python 终极篇 ---- 中间件
  3. java 变量的命名
  4. 读书笔记-架构整洁之道有感
  5. VB中On Error Resume Next 什么意思,一般在什么情况下使用
  6. canvas字体加粗
  7. 阿里云服务器价格是多少,阿里云服务器价格查询的三种方式
  8. 朱志坤计算机学院,厦门工学院第七届田径运动会竞赛规程.doc
  9. 量化分析基本框架示例
  10. server服务器系统2019安装,windowsserver 2019系统安装教程图文详解