這個面積,和上次聯(lián)想杯的那個單調(diào)棧的題目的維護方式很像,可以利用一個數(shù)組記錄一下前置狀態(tài),然后用 dp 的思想轉(zhuǎn)移,或者也可以直接維護一個變量 sum 用來實時維護面積和,我是使用第二個方法實現(xiàn)的,只需要在彈棧的時候減去舍棄掉的部分的面積就好了
代碼: ?
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e3+100;const int mod=1e9+7;char maze[N][N];LL dp[N][N];int main()
{
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%s",maze[i]+1);for(int i=n;i>=1;i--)for(int j=1;j<=m;j++){if(maze[i][j]=='X')dp[i][j]=0;elsedp[i][j]=dp[i+1][j]+1;}LL ans=0;for(int i=1;i<=n;i++){stack<int>st;st.push(0);LL sum=0;for(int j=1;j<=m;j++){while(st.size()&&dp[i][st.top()]>dp[i][j]){int pre=st.top();st.pop();sum=(sum-(pre-st.top())*dp[i][pre]%mod+mod)%mod;}sum=(sum+(j-st.top())*dp[i][j]%mod)%mod;ans=(ans+sum)%mod;st.push(j);}}printf("%lld\n",ans);return 0;
}