bzoj4165 矩阵 堆维护多路归并
题目传送门
https://lydsy.com/JudgeOnline/problem.php?id=4165
题解
大概多路归并是最很重要的知识点了吧,近几年考察也挺多的(虽然都是作为签到题的)。
看到题目要求第 \(K\) 小矩阵,基本上可以想到用堆维护的 \(K\) 路归并。
然后我们考虑每一路是以 \((x_2, y_2)\) 为右下角的矩形的权值。那么初始的矩形的左上角应该是 \((x_2 - Mina, y_2 - Minb)\)。
于是我们用一个堆来维护这样的每一路。扩展每一路的话,因为把矩形的左边界或者上边界扩展一个单位以后权值肯定单调升,所以可以直接扩展一下左边界和上边界这两个矩形。但是这样可能会有重复的,所以拿一个 map
来判重一下。
这样的时间复杂度是 \(O(k\log nm)\)。
#include<bits/stdc++.h>
#include<tr1/unordered_set>
#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back
template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}
typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
}
const int N = 1000 + 7;
int n, m, mina, minb, k;
int a[N][N];
ll s[N][N];
inline ll gsum(int x1, int y1, int x2, int y2) { return s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]; }
struct Matrix {
int x1, y1, x2, y2;
inline Matrix() {}
inline Matrix(const int &x1, const int &y1, const int &x2, const int &y2) : x1(x1), y1(y1), x2(x2), y2(y2) {}
inline bool operator < (const Matrix &b) const { return gsum(x1, y1, x2, y2) > gsum(b.x1, b.y1, b.x2, b.y2); }
};
std::priority_queue<Matrix> q;
std::tr1::unordered_set<ll> mp;
inline void set_mp(int x1, int y1, int x2, int y2) {
ll v = (((((ll)x1 * m) + y1) * n + x2) * m + y2);
mp.insert(v);
}
inline bool get_mp(int x1, int y1, int x2, int y2) {
ll v = (((((ll)x1 * m) + y1) * n + x2) * m + y2);
return mp.count(v);
}
inline void work() {
for (int i = mina; i <= n; ++i)
for (int j = minb; j <= m; ++j) q.push(Matrix(i - mina + 1, j - minb + 1, i, j)), set_mp(i - mina + 1, j - minb + 1, i, j);
while (k--) {
Matrix t = q.top();
q.pop();
if (!k) return (void)printf("%lld\n", gsum(t.x1, t.y1, t.x2, t.y2));
if(t.x1 > 1 && !get_mp(t.x1 - 1, t.y1, t.x2, t.y2)) set_mp(t.x1 - 1, t.y1, t.x2, t.y2), q.push(Matrix(t.x1 - 1, t.y1, t.x2, t.y2));
if(t.y1 > 1 && !get_mp(t.x1, t.y1 - 1, t.x2, t.y2)) set_mp(t.x1, t.y1 - 1, t.x2, t.y2), q.push(Matrix(t.x1, t.y1 - 1, t.x2, t.y2));
}
}
inline void init() {
read(n), read(m), read(mina), read(minb), read(k);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) read(a[i][j]), s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
}
int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}
bzoj4165 矩阵 堆维护多路归并的更多相关文章
- bzoj4165: 矩阵(堆+hash)
求第k大用堆维护最值并出堆的时候扩展的经典题... 因为只有正数,所以一个矩阵的权值肯定比它的任意子矩阵的权值大,那么一开始把所有满足条件的最小矩阵加进堆里,弹出的时候上下左右扩展一行加进堆,用has ...
- 【bzoj4165】矩阵 堆+STL-map
题目描述 定义和谐矩阵为长不小于 Mina 且宽不小于 Minb 的矩阵,矩阵的权值为整个矩阵内所有数的和.给定一个长为 N,宽为 M 的矩阵 A,求它的所有和谐子矩阵中权值第 K 小的矩阵,并输出它 ...
- UVA 11997 K Smallest Sums (多路归并)
从包含k个整数的k个数组中各选一个求和,在所有的和中选最小的k个值. 思路是多路归并,对于两个长度为k的有序表按一定顺序选两个数字组成和,(B表已经有序)会形成n个有序表 A1+B1<=A1+B ...
- bzoj4165: 矩阵
Description 定义和谐矩阵为长不小于 Mina 且宽不小于 Minb 的矩阵,矩阵的权值为整个矩阵内所有数的和.给定一个长为 N ,宽为 M 的矩阵 A,求它的所有和谐子矩阵中权值第 K 小 ...
- UVA11997求前k个和,多路归并问题
题意: 给你一个二维矩阵,n*n的,每次从每一行中拿出来一个,然后加起来组成一个和,一共可以得到n^n个和,要求求出这n^n个和中最小的那n个和. 思路: 多路归并问题,先说下多路 ...
- uva 11997 K Smallest Sums 优先队列处理多路归并问题
题意:K个数组每组K个值,每次从一组中选一个,共K^k种,问前K个小的. 思路:优先队列处理多路归并,每个状态含有K个元素.详见刘汝佳算法指南. #include<iostream> #i ...
- [UOJ#268]. 【清华集训2016】数据交互[动态dp+可删堆维护最长链]
题意 给出 \(n\) 个点的树,每个时刻可能出现一条路径 \(A_i\) 或者之前出现的某条路径 \(A_i\) 消失,每条路径有一个权值,求出在每个时刻过后能够找到的权值最大的路径(指所有和该路径 ...
- 【bzoj5210】最大连通子块和 树链剖分+线段树+可删除堆维护树形动态dp
题目描述 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块和. 其中,一棵子树的最大连通子块和指的是:该子树 ...
- POJ 2010 Moo University - Financial Aid(堆维护滑窗kth,二分)
按照score排序,贪心,从左到右用堆维护并且记录前面的最小N/2个花费之和. 然后从右向左枚举中位数,维护N/2个数之和加上并判断是否满足条件.(stl的队列没有clear(),只能一个一个pop. ...
随机推荐
- 【洛谷T89359 扫雷】
题目链接 这个题有一个十分简单的做法 我们可以考虑位运算 按位异或(^) 异或,英文为exclusive OR,缩写成xor 异或(xor)是一个数学运算符.它应用于逻辑运算.异或的数学符号为“⊕”, ...
- system系统调用返回值判断命令是否执行成功
system函数对返回值的处理,涉及3个阶段: 阶段1:创建子进程等准备工作.如果失败,返回-1. 阶段2:调用/bin/sh拉起shell脚本,如果拉起失败或者shell未正常执行结束(参见备注1) ...
- 【ASK】设置网卡启动遇到的事!
上次动笔是16年的事情了,一晃3年过去了.算了,不感慨了.直奔主题吧. 1.今天朋友要把一批win10的机器设置成网卡启动. 2.网卡是intel集成的. 3.按照主板说明已经设置成功. 4.通过wi ...
- 【MAC】 命令行解压缩 rar 文件
使用Mac解压rar文件很简单,总共分2步.step1:安装解压工具,step2:解压 1.使用Homebrew安装unrar brew install unrar 2.cd到rar文件的目录下,然后 ...
- [VBA]斐波那契数列
Sub 斐波那契()Dim arrFor i = 3 To 100Cells(1, 1) = 0Cells(2, 1) = 1Cells(i, 1) = Cells(i - 1, 1) + Cells ...
- pwa 总结
概述 前几天了解并按照官方文档,成功实现了一个小型的 pwa demo,现在把总结记录下来,供以后开发时参考,相信对其他人也有用. pwa pwa 包括很多内容,我这里只介绍一部分,因为比如 Push ...
- VBA文件操作
做这些东西主要是为了,实现,我们的最终目标. 查到 两个大表里面的变化数据. 所以 这次 ①实现了 文件操作的一部分内容. 包括,excel的打开.分四个步骤. 1.路径 2.打开工作博 3.操作 4 ...
- Command line is too long. Shorten command line for testMLDome1 or also for Application default configuration
在.idea文件夹中,更改workspace.xml文件 加这段语句: <property name="dynamic.classpath" value="true ...
- django 的多对多关系
django里自带的多对多表创建 其实就是两个多对一关系各自关联,在第三张表上 多对多的增加 add()可以传数值 例如 add(1)或数组 add(*[2,3]) 多对多反向操作 自己创建第三张表, ...
- TortoiseSVN-1.9.7 对应 eclipse svn 插件的 更新
用TortoiseSVN在文件夹导入项目之后,用eclipse 导入发现没有SVN信息,无法同步工程.出现这个情况先不管 TortoiseSVN的版本,直接把eclipse的svn版本升级到最新. H ...