hdu-6638 Snowy Smile
题目链接
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(−109≤xi,yi,wi≤109), 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
题意
平面上有n个点,每个点有价值\(w_i\),可以任意选一个矩形,获取矩形内所有点的值,求最大的价值和为多少
题解
先对所有点坐标离散化,枚举矩形上界,对于上界及以下的点,以y坐标相等的点为一组,按y从大到小,一组一组的插入线段树,每插入完一组点,用线段树求出当前的最大子段和,整个过程相当于在枚举矩形上下界,利用线段树维护最大子段和。
线段树每个节点维护:区间和,左端点向右最大子段和,右端点向左最大子段和,区间最大子段和,用类似区间合并的方式合并
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mx = 2005;
const ll INF = 1e18;
bool vis[mx][mx];
struct Node {
int x, y, w;
int p, q;
}node[mx];
vector <int> vx, vy;
vector <Node> mp[mx];
int getidx(int x) {
return lower_bound(vx.begin(), vx.end(), x) - vx.begin() + 1;
}
int getidy(int y) {
return lower_bound(vy.begin(), vy.end(), y) - vy.begin() + 1;
}
struct Tree {
ll sum;
ll Lans, Rans, ans;
}tree[mx<<2];
void pushUp(int rt) {
tree[rt].ans = max(max(tree[rt<<1].ans, tree[rt<<1|1].ans), tree[rt<<1].Rans+tree[rt<<1|1].Lans);
tree[rt].Lans = max(tree[rt<<1].Lans, tree[rt<<1].sum+tree[rt<<1|1].Lans);
tree[rt].Rans = max(tree[rt<<1|1].Rans, tree[rt<<1|1].sum+tree[rt<<1].Rans);
tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
}
void build(int l, int r, int rt) {
if (l == r) {
tree[rt].sum = tree[rt].Lans = tree[rt].Rans = tree[rt].ans = 0;
return;
}
int mid = (l + r) / 2;
build(l, mid, rt<<1);
build(mid+1, r, rt<<1|1);
pushUp(rt);
}
void update(int pos, int val, int l, int r, int rt) {
if (l == r) {
tree[rt].sum += val;
tree[rt].Lans = tree[rt].Rans = tree[rt].ans = tree[rt].sum;
return;
}
int mid = (l + r) / 2;
if (pos <= mid) update(pos, val, l, mid, rt<<1);
else update(pos, val, mid+1, r, rt<<1|1);
pushUp(rt);
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
vx.clear(); vy.clear();
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d%d%d", &node[i].x, &node[i].y, &node[i].w);
vx.push_back(node[i].x);
vy.push_back(node[i].y);
}
sort(vx.begin(), vx.end()); sort(vy.begin(), vy.end());
vx.erase(unique(vx.begin(), vx.end()), vx.end());
vy.erase(unique(vy.begin(), vy.end()), vy.end());
for (int i = 1; i <= n; i++) {
node[i].p = getidx(node[i].x);
node[i].q = getidy(node[i].y);
}
for (int i = 1; i <= vy.size(); i++) mp[i].clear();
for (int i = 1; i <= n; i++) mp[node[i].q].push_back(node[i]);
ll ans = 0;
for (int i = 1; i <= vy.size(); i++) {
build(1, vx.size(), 1);
for (int j = i; j <= vy.size(); j++) {
for (int k = 0; k < mp[j].size(); k++) {
Node tmp = mp[j][k];
update(tmp.p, tmp.w, 1, vx.size(), 1);
}
ans = max(ans, tree[1].ans);
}
}
printf("%lld\n", ans);
}
return 0;
}
hdu-6638 Snowy Smile的更多相关文章
- HDU 6638 - Snowy Smile 线段树区间合并+暴力枚举
HDU 6638 - Snowy Smile 题意 给你\(n\)个点的坐标\((x,\ y)\)和对应的权值\(w\),让你找到一个矩形,使这个矩阵里面点的权值总和最大. 思路 先离散化纵坐标\(y ...
- 最大矩阵覆盖权值--(静态连续最大子段 (线段树) )-HDU(6638)Snowy Smile
这题是杭电多校2019第六场的题目 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6638 题意:给你平面上n个点,每个点都有权值(有负权),让你计算一 ...
- 2019杭电多校第六场hdu6638 Snowy Smile(线段树+枚举)
Snowy Smile 题目传送门 解题思路 先把y离散化,然后把点按照x的大小进行排序,我们枚举每一种x作为上边界,然后再枚举其对应的每一种下边界.按照这种顺序插入点,这是一个压维的操作,即在线段树 ...
- 2019杭电暑假多校训练 第六场 Snowy Smile HDU - 6638
很多题解都是简单带过,所以打算自己写一篇,顺便也加深自己理解 前置知识:线段树.线段树维护最大字段和.二维坐标离散化 题解: 1.很容易想到我们需要枚举所有子矩阵来得到一个最大子矩阵,所以我们的任务是 ...
- 2019杭电多校6 hdu6638 Snowy Smile(二维最大矩阵和 线段树)
http://acm.hdu.edu.cn/showproblem.php?pid=6638 题意:给你一些点的权值,让找一个矩形圈住一部分点,问圈住点的最大权值和 分析:由于是稀疏图,明显要先把x, ...
- [2019杭电多校第六场][hdu6638]Snowy Smile(维护区间最大子段和)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6638 题意为在一个平面上任意选择一个长方形,使得长方形内点权和最大. 因为长方形可以任意选择,所以上下 ...
- 2019 Multi-University Training Contest 7 - 1006 - Snowy Smile - 线段树
http://acm.hdu.edu.cn/showproblem.php?pid=6638 偷学一波潘哥的二维离散化和线段树维护最大子段和. 思路是枚举上下边界,但是不需要从左到右用最大子段和dp. ...
- 【HDOJ6638】Snowy Smile(线段树)
题意:一个二维平面上有n个点,每个点的坐标是(x[i],y[i]),权值是w[i] 求一个矩形使得其中所有点的权值和最大,输出权值和 n<=2e3,x[i],y[i],w[i]的绝对值<= ...
- 2019 Multi-University Training Contest 6 Snowy Smile (最大字段和变形)
题意: 求一个子矩阵要求其矩阵内的合最大. 题解: 正常的求最大子矩阵的复杂度是O(n^3) 对于这一题说复杂度过不去,注意到这个题总共只有2000个点关键点在与这里优化 最大子矩阵可以压缩矩阵变成最 ...
随机推荐
- 细说RESTFul API之版本管理
目录 接口实现版本管理的意义 如何实现接口的版本管理 项目实战 接口实现版本管理的意义 API版本管理的重要性不言而喻,对于API的设计者和使用者而言,版本管理都有着非常重要的意义. 首先,对于API ...
- 机器学习经典分类算法 —— k-均值算法(附python实现代码及数据集)
目录 工作原理 python实现 算法实战 对mnist数据集进行聚类 小结 附录 工作原理 聚类是一种无监督的学习,它将相似的对象归到同一个簇中.类似于全自动分类(自动的意思是连类别都是自动构建的) ...
- DevOps相关知识点
DevOps 持续集成 简述 持续集成简称CI,是软件的开发和发布标准流程的最重要的部分 作为一个开发实践,在C中可以通过自动化等手段高频地去获取产品反馈并响应反馈的过程 简单的来说,持续集成就是持续 ...
- Java性能权威指南读书笔记--之一
JIT(即时编译) 解释型代码:程序可移植,相同的代码在任何有适当解释器的机器上,都能运行,但是速度慢. 编译型代码:速度快,电视不同CPU平台的代码无法兼容. java则是使用java的编译器先将其 ...
- AndroidSDK的目录详解
Tools 目录工具(必须的工具) Android SDK Tools(必须,只需下载一个版本,一般选最新版本):基础工具包,版本号带rc字样的是预览版. Android SDK Platform-t ...
- Kafka面试,看这篇文章就够了
原文链接:https://mp.weixin.qq.com/s/zxPz_aFEMrshApZQ727h4g** 引言 MQ(消息队列)是跨进程通信的方式之一,可理解为异步rpc,上游系统对调用结果的 ...
- android ——Intent
Intent是android程序中各组件之间进行交互的重要方式,它可以用于指明当前组件想要执行的动作,也可以在不同组件之间传递数据,Intent一般被用于启动活动,启动服务以及发送广播. 一.显式的使 ...
- SonarQube部署及代码质量扫描入门教程
一.前言 1.本文主要内容 CentOS7下SonarQube部署 Maven扫描Java项目并将扫描结果提交到SonarQube Server SonarQube扫描报表介绍 2.环境信息 工具/环 ...
- 《深入理解Java虚拟机》- Java虚拟机是如何加载Java类的?
Java虚拟机是如何加载Java类的? 这个问题也就是面试常问到的Java类加载机制.在年初面试百战之后,菜鸟喜鹊也是能把这流程倒背如流啊!但是,也只是字面上的背诵,根本就是像上学时背书考试一样. ...
- 7.4 元组tuple类型内置方法
元组tuple 元组相当于不可变的列表,在定义完成后后面就不可以进行更改,因此元组只可取不可存 因为不可变,所以相对列表来说,他的功能也少了很多,所以,不难理解,他有个优点就是占用内存小. 作用:能够 ...