题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6638

题意为在一个平面上任意选择一个长方形,使得长方形内点权和最大。

因为长方形可以任意选择,所以上下边一定在某些点上。所以可以枚举上下边。

将上下边看成一条直线y,上下边之间的点看成直线y上的点,则题意就转化成求直线y上最大子段和(子段和的左右边界即是长方形的左右边)。

用线段树维护(区间和&最大前缀和&最大后缀和)就可以维护得到区间最大子段和。

显然需要离散化(雾

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define lson l, mid, i << 1
#define rson mid + 1, r, i << 1 | 1
using namespace std;
typedef long long ll;
const int maxn = + ;
struct node {
ll sum, max_sum, max_q, max_h;//区间和,区间最大子段和,最大前缀和,最大后缀和。
}T[maxn * ];
struct P {
int x, y;
ll w;
}p[maxn];
int x[maxn], y[maxn];
bool cmp(P a, P b) {
if (a.y == b.y)
return a.x < b.x;
return a.y < b.y;
}
void up(int i) {
T[i].sum = T[i << ].sum + T[i << | ].sum;
T[i].max_sum = max(T[i << | ].max_q + T[i << ].max_h, max(T[i << ].max_sum, T[i << | ].max_sum));
T[i].max_q = max(T[i << ].max_q, T[i << ].sum + T[i << | ].max_q);
T[i].max_h = max(T[i << | ].max_h, T[i << ].max_h + T[i << | ].sum);
}
void build(int l, int r, int i) {
T[i].sum = T[i].max_sum = T[i].max_q = T[i].max_h = ;
if (l == r)
return;
int mid = l + r >> ;
build(lson);
build(rson);
}
void update(int pos, int w, int l, int r, int i) {
if (l == r) {
T[i].sum += w;
T[i].max_sum = T[i].max_q = T[i].max_h = T[i].sum;
return;
}
int mid = l + r >> ;
if (pos <= mid)
update(pos, w, lson);
else
update(pos, w, rson);
up(i);
}
ll f[maxn];
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n;
ll ans = ;
scanf("%d", &n);
for (int i = ; i <= n; i++) {
scanf("%d%d%lld", &p[i].x, &p[i].y, &p[i].w);
x[i] = p[i].x, y[i] = p[i].y;
}
sort(x + , x + + n);
sort(y + , y + + n);
int xx = unique(x + , x + + n) - x - , yy = unique(y + , y + + n) - y - ;
for (int i = ; i <= n; i++) {
p[i].x = lower_bound(x + , x + + xx, p[i].x) - x;
p[i].y = lower_bound(y + , y + + yy, p[i].y) - y;
}
sort(p + , p + + n, cmp);
int now = ;
for (int i = ; i <= yy; i++) {
build(, xx, );
for (int j = i, k = now; j <= yy; j++) {
while (k <= n && p[k].y == j) {
update(p[k].x, p[k].w, , xx, );
k++;
}
if (j == i)
now = k;
ans = max(ans, T[].max_sum);
}
}
printf("%lld\n", ans);
}
}

最新文章

  1. Mac 编写oracle 连接脚本
  2. android数据库SQLite的设计模式
  3. clone github的代码
  4. OC之160728
  5. 利用SCI做的一个足球答题系统
  6. Maximal Square 我们都在寻找最高1子矩阵(leeCode)
  7. 理解JNDI中 java:comp/env/jdbc/datasource 与 jdbc/datasource 的不同之处(转)
  8. MyEclipse下打开ftl文件
  9. 微信小程序爬坑
  10. [Swift]LeetCode98. 验证二叉搜索树 | Validate Binary Search Tree
  11. pcntl_exec()
  12. 在平衡树的海洋中畅游(一)——Treap
  13. 把旧系统迁移到.Net Core 2.0 日记(3) - 详解依赖注入 (转)
  14. Sublime Text 之运行 js 方法[2015-5-6更新mac下执行js]
  15. C#(Winform)中button的Enable=false和visible的区别
  16. 【动态规划】POJ-3616
  17. Java 和 Python 解析动态 key 的 JSON 数据
  18. Java知多少虚拟机(JVM)以及跨平台原理
  19. .Net 上传文件到ftp服务器和下载文件
  20. HDU 2084 数塔 (dp)

热门文章

  1. zip(), dict(), itertools.repeat(), list(迭代器)
  2. hash详细介绍
  3. flask入门,Hello World!
  4. 命令——tree
  5. 51nod1790 输出二进制数
  6. linux运维、架构之路-linux目录结构
  7. C#项目类型分三种,Dos(控制台),c/s(客户端与服务器),b/s(浏览器/服务器)
  8. android 7.0适配(总结)
  9. input 的 type 等于 file
  10. which statement is true for the class java.util.ArrayList?