很多题解都是简单带过,所以打算自己写一篇,顺便也加深自己理解

前置知识:线段树、线段树维护最大字段和、二维坐标离散化

题解:

1.很容易想到我们需要枚举所有子矩阵来得到一个最大子矩阵,所以我们的任务是 “枚举所有子矩阵”,

 二维前缀和暴力枚举达到O(n^4),  DP结合前缀和枚举也需要O(n^3),然而我们的时间需要更少.

2.可以看到坐标范围为 -10^9~10^,但是点 n<=2000个,所以我们需要先将点 离散化。

3.将点 按y轴高度排序,枚举矩阵的上下界,这将达到O(n^2)了。

4.最重点的一步,将矩阵内的点 加入线段树维护。下面解释下这一步。

 首先假设我们枚举的这一个矩阵的 上界为 up ,下界为 down ,目前的矩阵的宽度就已经知道是 up-down。

 所以现在我们剩下的任务就是“枚举矩阵宽度” 来达到  “枚举宽度为up-down的所有子矩阵,找出宽度为up-down的最大子矩阵”。

 我们宽度已知,所有要枚举也就是长度,这样我们可以把 “矩阵压缩称为一条线”。

 这时候线段树的功能就能解决这个问题了。

 用线段树来维护最大字段和,其实维护的是 “宽度为up-down”的最大矩阵和。

 这样我们的时间复杂度就可以达到O(n^2 logn)了。

 记得每次改变下界的时候要初始化线段树,关于这个初始化代码中还有一个小技巧,差不多减少了1.5s左右的时间。

#include <bits/stdc++.h>using namespace std;
typedef double dou;
typedef  long long ll;
typedef pair<int, int> pii;
typedef map<int, int> mii;#define pai acos(-1.0)
#define M 4005
#define inf 0x3f3f3f3f
#define mod 1000000007
#define IN inline
#define left k<<1
#define right k<<1|1
#define lson L, mid, left
#define rson mid + 1, R, right
#define W(a) while(a)
#define lowbit(a) a&(-a)
#define ms(a,b) memset(a,b,sizeof(a))
#define Abs(a) (a ^ (a >> 31)) - (a >> 31)
#define false_stdio ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)int T, n;
ll vx[M], vy[M];
ll xlen, ylen, pos, ans;
struct Data {int x, y, val;bool operator <(Data& t) {return y < t.y;}
}node[M];
struct Data_t {ll sum;ll Lmax, Rmax, Max;
}tree[M << 2];IN void Updata(int L, int R, int k, int id,int add) {if (L == R) {tree[k].sum += (ll)add;tree[k].Lmax = tree[k].Rmax = tree[k].Max = tree[k].sum;return;}int mid = L + R >> 1;if (id <= mid)Updata(lson, id, add);else Updata(rson, id, add);//维护最大字段和tree[k].sum = tree[left].sum + tree[right].sum;tree[k].Lmax = max(tree[left].Lmax, tree[left].sum + tree[right].Lmax);tree[k].Rmax = max(tree[right].Rmax, tree[right].sum + tree[left].Rmax);tree[k].Max = max(max(tree[left].Max, tree[right].Max), tree[left].Rmax + tree[right].Lmax);
}int main() {false_stdio;cin >> T;W(T--) {cin >> n;for (int i = 1; i <= n; i++) {cin >> node[i].x >> node[i].y >> node[i].val;vx[i] = node[i].x, vy[i] = node[i].y;}//二维坐标离散化sort(vx + 1, vx + n + 1);sort(vy + 1, vy + n + 1);xlen = unique(vx + 1, vx + n + 1) - vx - 1;ylen = unique(vy + 1, vy + n + 1) - vy - 1;for (int i = 1; i <= n; i++) {node[i].x = lower_bound(vx + 1, vx + xlen + 1, node[i].x) - vx;node[i].y = lower_bound(vy + 1, vy + ylen + 1, node[i].y) - vy;}sort(node + 1, node + n + 1);ans = 0;//首先枚举下界for (int dw = 1; dw <= ylen; dw++) {pos = 1;memset(tree, 0, (xlen * 4 + 5) * sizeof(Data_t));//初始化线段树,离散化完有多少个点就初始化多大
W(node[pos].y < dw && pos <= n)pos++;//直接跳过小于下界的点for (int up = dw; up <= ylen; up++) {//枚举上界W(pos <= n && node[pos].y <= up) {//将上界与下届之间的点加入线段树中Updata(1, xlen, 1, node[pos].x, node[pos].val);pos++;}ans = max(ans, tree[1].Max);}}cout << ans << endl;}return 0;
}

转载于:https://www.cnblogs.com/caibingxu/p/11364440.html

2019杭电暑假多校训练 第六场 Snowy Smile HDU - 6638相关推荐

  1. 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第一场)

    杭电多校第一场属实恐怖,我连补题的冲动都莫得了. 本来还想说按去年的经验来说,杭电是要比牛客稍微友好那么一丢丢的吧.结果当场打脸,签到题来了个最短路*2+网络流,这谁顶得住啊. 所以这两天都没在补这场 ...

  2. 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第二场)

    这段时间自己都不知道该干些什么,比赛时候什么都想不到,全靠队友A题维持生计这样...补题进度也是一拖再拖,明后天又是两场连打,感觉又要堆一堆题了...看着补算了. 以下题解包括: \[1005[HDU ...

  3. 2019牛客暑假多校训练 第四场 triples I 按位或运算

    链接:https://ac.nowcoder.com/acm/contest/884/D 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...

  4. 2018杭电暑假多校知识点总结(附大一结语)

    大学的第一个年头就这样过去了,在这一年里,有着迷茫也有着奋斗,可惜没有什么汗水.我有不幸,不幸调剂到了软件工程这个陌生的专业,但我却又是幸运的,因为我遇到了一位优秀的学长,在他的指导下才步入了ACM的 ...

  5. 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第四场)

    本来想说这场放掉了,算了还是补了吧... 以下题解包括: \[1001[HDU-6614] \\ 1003[HDU-6616] \\ 1007[HDU-6620] \\ 1008[HDU-6621] ...

  6. 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第五场)

    开启疯狂水题解模式,大概会持续好几次...直到我赶上进度为止. 以下题解包括: \[1001[HDU-6624] \\ 1004[HDU-6627] \\ 1005[HDU-6628] \\ 1006 ...

  7. 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第六场)

    我胡汉三又滚回来了....保质期过了的题也得记下来. 以下题解包括: \[1002[HDU-6635] \\ 1005[HDU-6638] \\ 1006[HDU-6639] \\ 1008[HDU- ...

  8. 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第三场)

    以下题解包括: \[1002[HDU-6604] \\ 1004[HDU-6606] \\ 1006[HDU-6608] \\ 1007[HDU-6609] \\ 1009[HDU-6611]\] [ ...

  9. 2019牛客网暑假多校训练第四场 K —number

    链接:https://ac.nowcoder.com/acm/contest/884/K 来源:牛客网 题目描述 300iq loves numbers who are multiple of 300 ...

最新文章

  1. COM:根系-土壤-微生物互作
  2. 自律到极致-人生才精致:第11期 - 领奖通知
  3. 鼠标动效html,5种纯CSS3鼠标hover按钮动画效果
  4. python查看文档的软件_Python __doc__属性:查看文档
  5. xms跨平台基础框架 - 基于.netcore
  6. Mysql报错130_mysql 突然报错,连接不上
  7. 【 Grey Hack 】万金油脚本:常见端口获取shell
  8. CentOS7 搭建Pulsar 消息队列环境,CentOS(Linux)部署Pulsar,亲测成功,以及Python操作Pulsar实例驱动
  9. Windows的空格预览神器 | QuickLook
  10. c# Hello World
  11. 蚂蚁金服OceanBase“击败”甲骨文?呵呵!
  12. python实现Longest Common Subsequence最长公共子序列算法
  13. matlab求解多元函数的偏导数diff
  14. Linux系统中修复SambaCry漏洞(CVE-2017-7494)
  15. Angular CLI简介
  16. STM32【H7】理论——综述、HAL库简述
  17. 04.配置unp.h头文件出现开启 xinetd daytime 服务时 /etc/xinetd.d下 没有daytime 文件的解决办法
  18. 最近笔记本电脑开机启动正常,进入黑屏?
  19. OpenCV模板匹配和轮廓处理
  20. 做城市规划设计,如何下载地形图?

热门文章

  1. Android APK反编译得到Java源代码或资源文件
  2. [音乐欣赏]Craigie Hill
  3. C++ 容易犯错误的模型
  4. Python 懂车帝全车系销量排行榜
  5. Vue.js 2.x render 渲染函数 JSX
  6. learning hdmi edid protocol
  7. Javascript 思维导图 绘制基础内容(值得一看)
  8. STL中mem_fun与mem_fun_ref的区别[转]
  9. 提高jQuery执行效率
  10. Hive中文注释乱码解决方案