自古遭受各种奇怪码风的迫害
新学单调栈,代码思路参考本题第一条题解
#pragma GCC opitimize(2)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
const int N=2e3;
int n,m,ans;
int _m[N][N],_h[N],l[N],r[N];
void s_l(){
stack<int>s;
for(register int i=m;i>=1;--i){
while(!s.empty()&&_h[i]<=_h[s.top()]){
l[s.top()]=i;
s.pop();
}
s.push(i);
}
while(!s.empty()){
l[s.top()]=0;
s.pop();
}
}//左方高度小于等于
void s_r(){
stack<int>s;
for(register int i=1;i<=m;++i){
while(!s.empty()&&_h[i]<_h[s.top()]){
r[s.top()]=i;
s.pop();
}
s.push(i);
}
while(!s.empty()){
r[s.top()]=m+1;
s.pop();
}
}//右方高度小于
inline void read(int &x){
x=0;int f=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+(ch^48);
ch=getchar();
}
x*=f;
}
signed main(void){
read(n);read(m);
for(register int i=1;i<=n;++i)
for(register int j=1;j<=m;++j){
char c;
cin>>c;
if(c=='*')_m[i][j]=true;
}
for(register int i=1;i<=n;++i){
for(register int j=1;j<=m;++j){
++_h[j];
if(_m[i][j])_h[j]=0;
s_l();s_r();
}
for(register int k=1;k<=m;++k)
ans+=(k-l[k])*(r[k]-k)*_h[k];
}
cout<<ans;
return 0;
}
各位大佬求求了