题意:

给定一个矩阵,矩阵上有若干点,每个点有正或负的权值,找一个方框框住一些点使得方框中点权值最大。

题解:

离散化横纵坐标,容易将这个问题转化为在矩阵上求最大和子矩阵的问题。

普通的n*n的矩阵的子矩阵最大和正解为$O(n^3)$,枚举上下端点后dp

然而此题是一个稀疏矩阵,n*n矩阵中只有O(n)个点,要求$O(n^2logn)$解法。

正解是枚举上下端点,用线段树维护区间最大和,每枚举到一个下端点,将这个下端点上所有的点的权值更新到线段树上,每次更新logn

由于点的个数是O(n)的,因此每枚举一个上端点,最多更新线段树O(n)次,总时间复杂度$O(n^2logn)$

用线段树维护区间最大和,需要节点上保存如下信息:sum(总和),maxsum(最大子段和),lmax(最大前缀和),rmax(最大后缀和)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, LL>P;
const int M = 2e3 + ;
const LL mod = ;
const LL lINF = 0x3f3f3f3f3f3f3f3f;
#define ls (rt<<1)
#define rs (rt<<1|1)
LL gcd(LL a, LL b) { return b ? gcd(b, a%b) : a; }
struct node {
int l, r;
LL sum, lsmx, rsmx, mx;
}tr[M * ];
LL a[M];
LL pre, ans;//pre前一个搜索区间从右端点开始的最大子段和,ans当前最大值
void pushup(int rt)
{
tr[rt].sum = tr[ls].sum + tr[rs].sum;
tr[rt].lsmx = max(tr[ls].sum + tr[rs].lsmx,tr[ls].lsmx);
tr[rt].rsmx = max(tr[rs].sum + tr[ls].rsmx,tr[rs].rsmx);
tr[rt].mx = max(max(tr[ls].mx, tr[rs].mx), tr[ls].rsmx + tr[rs].lsmx);
}
void build(int rt, int l, int r)
{
tr[rt].l = l, tr[rt].r = r;
if (l == r)
{
tr[rt].sum += a[l];
tr[rt].lsmx += a[l];
tr[rt].rsmx += a[l];
tr[rt].mx += a[l];
return;
}
int mid = (l + r) >> ;
build(ls, l, mid);
build(rs, mid + , r);
pushup(rt);
}
void update(int rt, int l, int r, int pos, LL v)
{
if (l == r)
{
tr[rt].sum += v;
tr[rt].lsmx += v;
tr[rt].rsmx += v;
tr[rt].mx += v;
return;
}
int mid = (l + r) >> ;
if (pos <= mid)
update(ls, l, mid, pos, v);
else
update(rs, mid + , r, pos, v);
pushup(rt);
}
void query(int rt, int ql, int qr)
{
if (ql <= tr[rt].l&&tr[rt].r <= qr)
{
ans = max(ans, tr[rt].mx);
ans = max(ans, pre + tr[rt].lsmx);
pre = max(pre + tr[rt].sum, tr[rt].rsmx);
return;
}
int mid = (tr[rt].l + tr[rt].r) >> ;
if (ql <= mid)
{
query(ls, ql, qr);
}
if (qr > mid)
{
query(rs, ql, qr);
} }
int n;
int q;
LL x[M], y[M], val[M];
LL xid[M], yid[M];
int xsz, ysz;
vector<P>ve[M];
int main()
{
int _;
scanf("%d", &_);
while (_--)
{
scanf("%d", &n);
for (int i = ; i <= n; i++)
{
scanf("%lld%lld%lld", &x[i], &y[i], &val[i]);
xid[i] = x[i];
yid[i] = y[i];
}
sort(yid + , yid + + n);
sort(xid + , xid + + n);
xsz = unique(xid + , xid + + n) - (xid + );
ysz = unique(yid + , yid + + n) - (yid + );
for (int i = ; i <= ysz; i++)
{
ve[i].clear();
}
for (int i = ; i <= n; i++)
{
int xi, yi;
xi = lower_bound(xid + , xid + + xsz, x[i]) - xid;
yi = lower_bound(yid + , yid + + ysz, y[i]) - yid;
ve[yi].push_back(make_pair(xi, val[i]));
}
ans = ;
for (int i = ; i <= ysz; i++)//下边界
{
memset(tr, , sizeof tr);
for (int j = i; j >= ; j--)//上边界
{
for (auto tmp : ve[j])
{
update(, , xsz, tmp.first, tmp.second);
}
ans = max(ans, tr[].mx);
}
}
printf("%lld\n", ans);
}
}

hdu多校第六场1005 (hdu6638) Snowy Smilel 线段树/区间最大和的更多相关文章

  1. HDU多校第三场 Hdu6606 Distribution of books 线段树优化DP

    Hdu6606 Distribution of books 题意 把一段连续的数字分成k段,不能有空段且段和段之间不能有间隔,但是可以舍去一部分后缀数字,求\(min(max((\sum ai ))\ ...

  2. HDU 4509 湫湫系列故事——减肥记II(线段树-区间覆盖 或者 暴力技巧)

    http://acm.hdu.edu.cn/showproblem.php?pid=4509 题目大意: 中文意义,应该能懂. 解题思路: 因为题目给的时间是一天24小时,而且还有分钟.为了解题方便, ...

  3. HDU 6638 - Snowy Smile 线段树区间合并+暴力枚举

    HDU 6638 - Snowy Smile 题意 给你\(n\)个点的坐标\((x,\ y)\)和对应的权值\(w\),让你找到一个矩形,使这个矩阵里面点的权值总和最大. 思路 先离散化纵坐标\(y ...

  4. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  5. [2019杭电多校第三场][hdu6609]Find the answer(线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6609 大致题意是求出每个位置i最小需要将几个位置j变为0(j<i),使得$\sum_{j=1}^ ...

  6. 吉首大学校赛 K 白山茶与红玫瑰 (线段树区间操作)

    链接:https://ac.nowcoder.com/acm/contest/925/K来源:牛客网 题目描述 公元2019年6月22日,白山茶王国与红玫瑰王国展开大战,在世外仙境——天空花园处,双方 ...

  7. 2014多校第六场 1005 || HDU 4925 Apple Tree

    题目链接 题意 : 给你一块n×m的矩阵,每一个格子可以施肥或者是种苹果,种一颗苹果可以得到一个苹果,但是如果你在一个格子上施了肥,那么所有与该格子相邻(指上下左右)的有苹果树的地方最后得到的苹果是两 ...

  8. hdu多校第五场1005 (hdu6628) permutation 1 排列/康托展开/暴力

    题意: 定义一个排列的差分为后一项减前一项之差构成的数列,求对于n个数的排列,差分的字典序第k小的那个,n<=20,k<=1e4. 题解: 暴力打表找一遍规律,会发现,对于n个数的排列,如 ...

  9. 2014 HDU多校弟六场J题 【模拟斗地主】

    这是一道5Y的题目 有坑的地方我已在代码中注释好了 QAQ Ps:模拟题还是练的太少了,速度不够快诶 //#pragma comment(linker, "/STACK:16777216&q ...

随机推荐

  1. Vue 指令大全

    准备开始本章要给大家带来的内容是相关Vue中的组件以及一系列常用属性.本章合适人群囊括了除已有开发经验人员以外的小白新手,从how.why.what三个角度来让大家理解并使用该技术历史介绍angula ...

  2. python判断文件的编码格式是否为UTF8 无BOM格式

    转自: https://www.cnblogs.com/ferraborghini/p/4951102.html https://www.cnblogs.com/Detector/p/8744992. ...

  3. Flex布局(二)

    接上一篇,说一下flex布局的实例,转自阮一峰老师的博客

  4. Service4

    DNS解析的作用• 为什么需要DNS系统– www.baidu.com 与 119.75.217.56,哪个更好记?– 互联网中的114查号台/导航员 • DNS服务器的功能– 正向解析:根据注册的域 ...

  5. php获取网页源码分行显示

    file(PHP 3, PHP 4 )file -- 把整个文件读入一个数组中说明:file ( string filename [, int use_include_path [, resource ...

  6. 为什么 Go 语言把类型放在后面

    不是为了与众不同.而是为了更加清晰易懂. Rob Pike 曾经在 Go 官方博客解释过这个问题(原文地址:http://blog.golang.org/gos-declaration-syntax) ...

  7. 9、TestNG介绍与安装

    介绍 TestNG是一个受JUnit和NUnit启发的测试框架,但引入了一些新功能,使其更加强大和易于使用,例如: 注释. 在任意大的线程池中运行你的测试,这些线程池有各种可用的策略(所有方法在他们自 ...

  8. MySQL数据库(一)—— 数据库介绍、MySQL安装、基础SQL语句

    数据库介绍.MySQL安装.基础SQL语句 一.数据库介绍 1.什么是数据库 数据库即存储数据的仓库 2.为什么要用数据库 (1)用文件存储是和硬盘打交道,是IO操作,所以有效率问题 (2)管理不方便 ...

  9. 如果手工启动chromedriver

    使用selenium模拟登陆网站时,有些网站会识别chrome driver里的json信息,从而判断是不是爬虫程序,做到反爬效果.(比如知乎) 下面说明下怎么手动启动chromedriver 1). ...

  10. ArcGis基础—shapefile矢量文件与lyr图层文件之间有何区别?

    shapefile (.shp) 是一种矢量数据存储格式,用于存储地理要素的位置.形状和属性. shapefile 存储在一组相关文件中,并包含一个要素类. 图层文件 (.lyr) 是存储源数据集路径 ...