CFGym - 101102D.Rectangles 单调栈+dp优化
来源:互联网 发布:php钓鱼源码 编辑:程序博客网 时间:2024/06/05 22:48
1. 题目描述:
Given an R×C gridwith each cell containing an integer, find the number of subrectangles in thisgrid that contain only one distinct integer; this means every cell in asubrectangle contains the same integer.
A subrectangle isdefined by two cells: the top left cell (r1, c1),and the bottom-right cell (r2, c2) (1 ≤ r1 ≤ r2 ≤ R) (1 ≤ c1 ≤ c2 ≤ C),assuming that rows are numbered from top to bottom and columns are numberedfrom left to right.
Input
The first line ofinput contains a single integer T, the number of test cases.
The first line ofeach test case contains two integers R and C (1 ≤ R, C ≤ 1000),the number of rows and the number of columns of the grid, respectively.
Each of thenext R lines contains C integers between 1 and 109,representing the values in the row.
Output
For each testcase, print the answer on a single line.
Example
Input
1
3 3
3 3 1
3 3 1
2 2 5
Output
16
2. 题意概述:
给你一个RxC矩阵,里面每一个矩阵元素中有一个数在1~1e9之间,求有多少个子矩阵里面的所有数相同?
3. 题解思路:
先对每一列从上到下遍历,用h[i][j]记录从当前元素往上最多有多少数相同, 然后对每一行遍历,用ans[i][j] 记录以a[i][j]为右下角的元素的子矩阵个数,那么我们可以发现:设当前元素之前同一行中小于它且最近的元素为a[i][k] 那么ans[i][j]=ans[i][k]+(j-k)*h[i][j]为了降低复杂度可以在当前行从左向右遍历的过程中把各列的高放入单调栈中,这样可以快速知道小于当前元素最近的元素的位置,最后对ans[][]求和就是结果 ;
4. Ac代码:
#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <algorithm>#include <functional>#include <cmath>#include <vector>#include <queue>#include <map>#include <set>#include <ctime>#define INF 0x7fffffff#define maxn 1111#define eps 1e-6#define pi acos(-1.0)#define e 2.718281828459#define mod (int)1e9 + 7;using namespace std;typedef long long ll;int a[maxn][maxn], h[maxn][maxn], p[maxn][maxn], s[maxn * maxn];int main(){#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); long _begin_time = clock();#endif int r, c, t; scanf("%d", &t); while (t--) { memset(h, 0, sizeof(h)); memset(s, 0, sizeof(s)); memset(p, 0, sizeof(p)); scanf("%d%d", &r, &c); for (int i = 1; i <= r; i++) for (int j = 1; j <= c; j++) { scanf("%d", &a[i][j]); h[i][j] = a[i][j] == a[i - 1][j] ? h[i - 1][j] + 1 : 1; } int cnt =1; ll ans = 0; for (int i = 1; i <= r; i++) for (int j = 1; j <= c; j++) { if (a[i][j - 1] != a[i][j]) //不等则求之 { cnt = 1; s[1] = j - 1; // 单调栈初始化 h[i][j - 1] = 0; //无法延伸 s[++cnt] = j; p[i][j] = h[i][j]; ans += 1LL * p[i][j]; // 防爆 } else // 等则并之 { while (h[i][j] <= h[i][s[cnt]]) // 单调栈求比他小的第一个位置,顺便把大的元素全部出栈 cnt--; int pos = s[cnt]; // 记录下来 s[++cnt] = j; //入栈 p[i][j] += h[i][j] * (j - pos); // 求出来记录之 if (h[i][pos] != 0) p[i][j] += p[i][pos]; ans += 1LL * p[i][j]; } } printf("%lld\n", ans); }#ifndef ONLINE_JUDGE long _end_time = clock(); printf("time = %ld ms\n", _end_time - _begin_time);#endif return 0;}
- CFGym - 101102D.Rectangles 单调栈+dp优化
- Gym 101102D Rectangles 【单调栈】
- GYM 101102 D.Rectangles(单调栈)
- CF 373D Counting Rectangles is Fun 单调栈+DP
- CFgym:Memory Manager(dp & 单调队列优化)
- CFGym 101490D DP
- CFgym: Laying Cables(单调栈)
- 单调队列优化DP
- 单调队列优化DP
- dp单调队列优化
- 单调队列--优化dp
- 单调队列优化dp
- 单调队列优化DP
- 单调队列优化DP
- 单调队列优化dp
- CF Gym101102D Rectangles 单调栈(计数)
- Gym 101102D 单调栈
- D - Rectangles
- 各类优化方法总结
- 编程书籍阅读随谈(第四篇)
- LintCode 【平面列表】
- Java初学之数学函数的使用
- 图像的深度和通道概念区分
- CFGym - 101102D.Rectangles 单调栈+dp优化
- View移动的相关方法
- 二叉树中序与前序(或后序)解树
- 功耗优化方法
- display的作用和分类
- 颜色渐变工具类
- ACM 算法分类 与 具体题型
- Android客户端性能优化(魅族资深工程师毫无保留奉献)
- 环信集成导入详细介绍与填坑(一)