Codeforces 1195E OpenStreetMap 单调队列套单调队列
题意:给你一个n * m的矩阵,问所有的a * b的子矩阵的最小的元素的和是多少。题目给出了矩阵中的数的数据生成器。
思路:如果这个问题是1维的,即求所有区间的最小元素的和,用单调队列O(n)就可以做。对于这个问题,我们先给每一行建一个单调队列,枚举子矩阵的行坐标的左端点和右端点。在行的左右端点的基础上,用另一个单调队列维护子矩阵每一行的最小值。
代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define pii pair<int, int>
#define LL long long
#define db double
using namespace std;
const int maxn = 3001;
pii q[maxn];
int l, r;
int q3[maxn][maxn], l3[maxn], r3[maxn];
int a[maxn][maxn];
int n, m;
void init(int p, int L, int R) {
for (int j = L; j <= R; j++) {
int tmp = a[p][j];
while(l3[p] <= r3[p] && a[p][q3[p][r3[p]]] >= tmp) r3[p]--;
q3[p][++r3[p]] = j;
}
}
void maintain(int p, int L, int R) {
int tmp = a[p][R];
while(l3[p] <= r3[p] && q3[p][l3[p]] < L) l3[p]++;
while(l3[p] <= r3[p] && a[p][q3[p][r3[p]]] >= tmp) r3[p]--;
q3[p][++r3[p]] = R;
}
int query(int p) {
return a[p][q3[p][l3[p]]];
}
int main() {
int a1, b1, now, x, y, z;
scanf("%d%d%d%d", &n, &m, &a1, &b1);
scanf("%d%d%d%d", &now, &x, &y, &z);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
a[i][j] = now;
now = ((LL)now * x + y) % z;
}
}
for (int i = 1; i <= n; i++) l3[i] = 1;
LL ans = 0;
for (int i = 1; i <= n; i++) {
init(i, 1, b1 - 1);
}
for (int l1 = 1, r1 = b1; r1 <= m; l1++, r1++) {
l = 1, r = 0;
for (int j = 1; j <= a1; j++) {
maintain(j, l1, r1);
int tmp = query(j);
while(l <= r && q[r].second >= tmp) r--;
q[++r] = make_pair(j, tmp);
}
ans += q[l].second;
for (int l2 = 2, r2 = a1 + 1; r2 <= n; l2++, r2++) {
while(l <= r && q[l].first < l2) l++;
maintain(r2, l1, r1);
int tmp = query(r2);
while(l <= r && q[r].second >= tmp) r--;
q[++r] = make_pair(r2, tmp);
ans += q[l].second;
}
}
printf("%lld\n", ans);
}
Codeforces 1195E OpenStreetMap 单调队列套单调队列的更多相关文章
- Codeforces - 1195E - OpenStreetMap - 单调队列
https://codeforc.es/contest/1195/problem/E 一个能运行但是会T的版本,因为本质上还是\(O(nmab)\)的算法.每次\(O(ab)\)初始化矩阵中的可能有用 ...
- Codeforces 1195E. OpenStreetMap (单调队列)
题意:给出一个n*m的矩形.询问矩形上所有的a*b的小矩形的最小值之和. 解法:我们先对每一行用单调栈维护c[i][j]代表从原数组的mp[i][j]到mp[i][j+b-1]的最小值(具体维护方法是 ...
- bzoj 1171 并查集优化顺序枚举 | 线段树套单调队列
详见vfleaking在discuss里的题解. 收获: 当我们要顺序枚举一个序列,并且跳过某些元素,那么我们可以用并查集将要跳过的元素合并到一起,这样当一长串元素需要跳过时,可以O(1)跳过. 暴力 ...
- 【learning】 单调队列与单调栈用法详解
1.单调栈 单调栈是指一个栈内部的元素具有严格单调性的一种数据结构,分为单调递增栈和单调递减栈. 其具有以下两个性质: 1,满足栈底到栈顶的元素具有严格单调性. 2,满足栈的先进后出特性,越靠近栈顶的 ...
- 单调栈and单调队列(此文太多坑了,以后再填)
单调栈 单调栈是一种特殊的栈,特殊之处在于栈内的元素都保持一个单调性,可能为单调递增,也可能为单调递减. 性质: 单调栈里的元素具有单调性 元素加入栈前,会在栈顶端把破坏栈单调性的元素都删除 使用单调 ...
- 22.1.23Manacher算法、双端队列、单调栈
22.1.23Manacher算法.双端队列.单调栈 1.Manacher算法 1)用途: Manacher算法用于解决类似求某个字符串中最长的回文子串.(回文就是正着读和倒着读一样的结构). 2)算 ...
- JAVA多线程(二) 并发队列和阻塞队列
github代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service/ ...
- C ~ 链式队列与循环队列
此处的链式与循环队列可以应用于BFS和树的层序遍历.下面是对其结构和基本操作的程序描述. 1.循环队列 解决循环队列的队空和队满的方法: [1].增加一个参数count,用来记录数组中当前 ...
- C语言 复杂队列(链表队列)
//复杂的队列二 --链表队列 #include<stdio.h> #include<stdlib.h> #define datatype int struct queueli ...
随机推荐
- bzoj4455 & loj2091 [Zjoi2016]小星星 容斥原理+树形DP(+状压DP?)
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4455 https://loj.ac/problem/2091 题解 很不错的一道题.(不过在当 ...
- SpringCloud-Nexfilx
1.概述 Spring Cloud Netflix provides Netflix OSS integrations for Spring Boot apps through autoconfigu ...
- docker Error response from daemon
docker 在拉取镜像的时候报错 Using default tag: latest Error response from daemon: Get https://registry-1.docke ...
- boost system
boost::system::error_code is the most basic class in Boost.System; it represents operating system-sp ...
- 如何在某个apps包下面中创建APP
- 【Java】SpringBoot 佛祖保佑banner.txt
最新写代码有点多,拜拜佛祖,代码不出bug. 在springboot项目的resources文件夹下面创建一个banner.txt文件,springboot启动的时候默认会加载这个文件 ${AnsiC ...
- 【Linux】运维常用命令
1.查看进程 ps -ef 如果需要查看特定的进程,比如redis的 ps -ef | grep redis 2.强制杀死进程 kill -9 进程id 3.忽略输出后台启动 nohup ./red ...
- Microsoft SQL Server(sql server 关系型数据库管理系统)
sql server一般指Microsoft SQL Server 关系型数据库管理系统 Microsoft SQL Server 是一个全面的数据库平台,使用集成的商业智能 (BI)工具提供了企业级 ...
- CodeForces - 1038D (线性DP)
题目:https://codeforces.com/problemset/problem/1038/D 题意:给你n个数字,每个数字可以吃左右两边的数,然后吃完后自己变成 a[i]-a[i+1]或者a ...
- python中匿名函数lamada函数的使用说明
匿名函数lambda是指一类无需定义标识符(函数名 )的一类函数式或子程序.lambda函数可以 接受多个任意参数,并且返回单个表达式的值. 它的意义在于即插即用类型,不必定义名字,方便.它需要的返回 ...