Problem Description
正如你所知道从前有一个人叫s_sin,她拥有着坐拥三千舰狼的梦想!然而天不遂人愿当她踏进hentai collection的大门之后,现实让她领略到了无情。身为一个坚强的妹子,她知道即使出门大破,即使十一连抽全是R,也要坚信着“玄不救非,氪不改命”,而自己是一个欧白这样最初的信仰!
有一天s_sin率领着她的舰狼们到达了某海峡,以一个N*M的矩阵表示,每一个元素为w或者b。其中b为暗礁,暗礁上是不允许有舰狼存在的。而s_sin也相信着一个道理,那就是只有把她的舰狼们组成矩形,她才能有足够的信仰在打败了最终boss之后捞到心仪的新舰狼。请问s_sin有多少种获取足够信仰的方法?(即在N*M的矩阵中有多少个全部由w组成的子矩形)
Input
输入第一行为一个正整数N,M表示有N行M列的矩阵。
接下来N行每行有M个字母为b或者w,如描述中所述。
Output
求N*M的矩阵中有多少个全部由w组成的子矩形。
Sample Input
2 3
bbb
www
2 2
bw
wb
Sample Output
6
2
Hint
1<=M,N<=2000
Source
福州大学第十二届程序设计竞赛
一行行考虑,单调栈维护,得到每一列最远可以往左边扩展到的位置
那么height[j] * len就是由这一列产生的,但是要注意,前面比这一列矮的列,向右扩展到这一列,其实还有矩形,所以要把那一列产生的矩形加上去
/*************************************************************************
> File Name: fzu2190.cpp
> Author: ALex
> Mail: [email protected]
> Created Time: 2015年05月10日 星期日 21时43分44秒
************************************************************************/
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;
static const int N = 2010;
char mat[N][N];
int height[N][N];
PLL Stack[N];
int Top;
int L[N];
int sum[N];
int main() {
int n, m;
while (~scanf("%d%d", &n, &m)) {
for (int i = 1; i <= n; ++i) {
scanf("%s", mat[i] + 1);
}
memset(height, 0, sizeof(height));
for (int i = 1; i <= m; ++i) {
height[i][0] = 0;
for (int j = 1; j <= n; ++j) {
height[i][j] = height[i][j - 1];
if (mat[j][i] == ‘w‘) {
++height[i][j];
}
else {
height[i][j] = 0;
}
}
}
LL ans = 0;
for (int i = 1; i <= n; ++i) {
Top = 0;
for (int j = m; j >= 1; --j) {
L[j] = j;
sum[j] = 0;
}
sum[0] = 0;
for (int j = m; j >= 1; --j) {
if (!Top) {
Stack[++Top] = make_pair(height[j][i], j);
}
else {
while (Top) {
PLL u = Stack[Top];
if (u.first <= height[j][i]) {
break;
}
L[u.second] = j + 1;
--Top;
}
Stack[++Top] = make_pair(height[j][i], j);
}
}
while (Top) {
PLL u = Stack[Top];
--Top;
L[u.second] = 1;
}
for (int j = 1; j <= m; ++j) {
if (!height[j][i]) {
continue;
}
int l = L[j];
sum[j] = (LL)height[j][i] * (j - l + 1);
if (l - 1 >= 1) {
sum[j] += sum[l - 1];
}
ans += sum[j];
}
}
printf("%lld\n", ans);
}
return 0;
}
时间: 2024-11-03 21:50:37