您的位置:首页 > 其它

Fzu-2190 非提的救赎 (单调栈)

2016-05-04 17:12 567 查看

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 3bbbwww2 2bwwb



Sample Output

62



Hint

1<=M,N<=2000

分析:单调栈的应用,计算每个w对答案的贡献。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct thing
{
long long n,x;
} stack[2001];
long long n,m,t,sum,ans,num[2001];
char c;
int main()
{
cin.sync_with_stdio(false);
while(cin>>n>>m)
{
memset(num,0,sizeof(num));
ans = 0;
for(int i = 1;i <= n;i++)
{
sum = t = 0;
for(int j = 1;j <= m;j++)
{
cin>>c;
if(c == 'b') num[j] = t = sum = 0;
else
{
num[j]++;
thing u;
u.x = num[j];
u.n = 1;
while(t && stack[t].x >= u.x)
{
sum -= stack[t].x*stack[t].n;
u.n += stack[t].n;
t--;
}
sum += u.x*u.n;
stack[++t] = u;
ans += sum;
}
}
}
cout<<ans<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: