#include <bits/stdc++.h>
#define long long long
using namespace std;
const int N = 2002;
struct block {
long h, l, r;
block(long h, long l, long r): h(h), l(l), r(r) {}
};
inline long get_agg1(block tmp) {
return (tmp.r-tmp.l+1) * tmp.h * (tmp.h + 1) / 2;
}
inline long get_agg2(block tmp) {
return (tmp.r * (tmp.r + 1) / 2 - tmp.l * (tmp.l - 1) / 2) * (tmp.h * (tmp.h + 1) / 2); // negative
}
int n, m, last[N], up[N][N];
char s[N][N];
long ans;
long brute() {
long actual = 0;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(s[i][j] == '#') continue;
int mn = up[i][j];
long res = 0;
for(int k = j; k >= 0; k--) {
mn = min(up[i][k], mn);
res += (mn * (mn + 1) / 2) * (j-k+1);
}
actual += res;
// cerr << res << ' ';
}
// cerr << endl;
}
return actual;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for(int i = 0; i < n; i++) cin >> s[i];
fill(last, last+N, -1);
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(s[i][j] == '#') last[j] = i;
else up[i][j] = i - last[j];
}
}
for(int i = 0; i < n; i++) {
vector<block> stk;
long sum1 = 0, sum2 = 0;
for(int j = 0, last = -1; j < m; j++) {
if(!up[i][j]) {
sum1 = 0;
sum2 = 0;
while(!stk.empty()) stk.pop_back();
last = j;
continue;
}
while(!stk.empty() && stk.back().h >= up[i][j]) {
block tmp = stk.back();
sum1 -= get_agg1(tmp);
sum2 += get_agg2(tmp);
stk.pop_back();
}
block tmp = block(up[i][j], (stk.empty() ? last : stk.back().r + 1), j - 1);
sum1 += get_agg1(tmp);
sum2 -= get_agg2(tmp);
stk.push_back(tmp);
// long res = 0;
// cerr << "pos " << i << ' ' << j << endl;
// for(block b: stk) {
// cerr << b.l << ' ' << b.r << ' ' << b.h << endl;
// res += get_agg1(b) * j - get_agg2(b);
// }
// cerr << res << endl;
// ans += res;
ans += sum1 * j + sum2; // sum2 is already negative
// cerr << i << ' ' << j << ' ' << sum1 * j + sum2 << ' ' << stk.size() << endl;
// cerr << tmp.r * (tmp.r + 1) / 2 - tmp.l * (tmp.l - 1) / 2 << ' ' << tmp.h * (tmp.h + 1) / 2 << ' ' << get_agg2(tmp) << ' ' << sum1 << ' ' << sum2 << endl;
}
}
cout << ans << endl;
//cout << brute() << endl;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
384 KB |
Output is correct |
2 |
Correct |
2 ms |
384 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
384 KB |
Output is correct |
2 |
Correct |
2 ms |
384 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
7 ms |
2560 KB |
Output is correct |
2 |
Correct |
8 ms |
2560 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
2560 KB |
Output is correct |
2 |
Correct |
7 ms |
2672 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
6 ms |
2560 KB |
Output is correct |
2 |
Correct |
8 ms |
2688 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
33 ms |
9720 KB |
Output is correct |
2 |
Correct |
77 ms |
16800 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
70 ms |
14840 KB |
Output is correct |
2 |
Correct |
118 ms |
20984 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
49 ms |
10232 KB |
Output is correct |
2 |
Correct |
86 ms |
17776 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
20 ms |
12544 KB |
Output is correct |
2 |
Correct |
77 ms |
20344 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
104 ms |
21368 KB |
Output is correct |
2 |
Correct |
100 ms |
21628 KB |
Output is correct |