CodeforcesGym - 101102D. Rectangles 单调栈+dp优化
2017-02-19 22:00
501 查看
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代码:
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; }
相关文章推荐
- Codeforces gym 101102 D 单调栈
- Codeforces gym 100971 D. Laying Cables 单调栈
- Codeforces gym 101102 K 想法
- Codeforces Gym - 101234J Zero Game [单调队列]
- Codeforces gym 101102 A dp
- [二分答案 2-SAT验证 前缀后缀优化建图 线段树优化建图] Codeforces gym 100159 Facebook Hacker Cup 2012 I. Unfriending
- Codeforeces Gym - 101635B Table [单调栈+DP]
- Gym 101102D Rectangles 【单调栈】
- Codeforces Gym 2015 ACM Arabella Collegiate Programming Contest
- codeforces Gym 100500H A. Potion of Immortality 简单DP
- CodeForcesGym 100524J Jingles of a String
- Codeforces Gym 100637A A. Nano alarm-clocks 前缀和的利用
- CodeForcesGym 100517H Hentium Scheduling
- CodeForces Gym 100500A A. Poetry Challenge DFS
- Lexicographically Maximum Subsequence CodeForces - 197C 单调栈
- Codeforces Gym 100500E IBM Chill Zone
- 【最短路】NEERC15 F Froggy Ford (Codeforces GYM 100851)
- 【codeforces Gym - 100187K】+ 构造 + 贪心
- Educational Codeforces Round 8(E. Zbazi in Zeydabad(树状数组优化))★ ★
- codeforces Gym - 101190A——Abbreviation