1.思路:
使用单调栈+继承的思想。维护一个单调递减栈,如果有要继承的格子,则继承栈顶元素,而不是上一个元素。
2.代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define node pair<int, int>
const int N = 3500 + 10;
int n;
int a[N][N];
int f[N];
int ans;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> a[i][j]; // 0空地1树
for (int i = 1; i <= n; i++) // 遍历行
{
stack<node> st; // first存储列号,second存储它的和
for (int j = 1; j <= n; j++) // 遍历列
{
if (a[i][j]) // 此时为树
{
f[j] = i;//f存此列最低的树的行号
}
while (!st.empty() && f[st.top().first] < f[j])//单调栈过程
{
st.pop();
}
if (st.empty())
{//不需继承,现在的元素即为第一个元素
st.push({j, 0});
st.top().second = (i - f[st.top().first]) * st.top().first;//行号的差*列
}
else
{//可以继承
node temp = st.top();
st.push({j, 0});
//行号的差*列号的差
st.top().second = temp.second + (i - f[st.top().first]) * (st.top().first - temp.first);
}
ans+=st.top().second;
}
}
cout<<ans;
return 0;
}