Submission #3414795
Source Code Expand
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
void cmax(int &x, int y) {
if (x < y) {
x = y;
}
}
void cmin(int &x, int y) {
if (x > y) {
x = y;
}
}
int main() {
#ifdef wxh010910
freopen("input.txt", "r", stdin);
#endif
int n;
cin >> n;
vector<string> board(n);
for (int i = 0; i < n; ++i) {
cin >> board[i];
}
long long answer = 0;
function<void(vector<string>)> solve = [&](vector<string> board) {
int n = board.size(), m = board[0].size();
if (n < m) {
vector<string> rotated(m, string(n, ' '));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
rotated[j][i] = board[i][j];
}
}
swap(n, m);
board = rotated;
}
if (m == 1) {
int sum = 0;
for (int i = 0; i < n; ++i) {
if (board[i][0] == '#') {
sum = 0;
} else {
answer += (board[i][0] - '0') * sum;
sum += board[i][0] - '0';
}
}
return;
}
vector<string> u = vector<string> (board.begin(), board.begin() + (n >> 1));
vector<string> d = vector<string> (board.begin() + (n >> 1), board.end());
solve(u);
solve(d);
u.push_back(d[0]);
int nu = n >> 1, nd = n + 1 >> 1;
vector<vector<int>> left(nd, vector<int> (m, inf));
vector<vector<int>> right(nd, vector<int> (m, -inf));
vector<int> top(m);
vector<int> bottom(m);
for (int i = 0; i < m; ++i) {
if (d[0][i] != '#') {
left[0][i] = right[0][i] = i;
}
}
for (int i = 0; i < nd; ++i) {
for (int j = 0; j < m; ++j) {
if (d[i][j] != '#') {
if (i) {
cmin(left[i][j], left[i - 1][j]);
cmax(right[i][j], right[i - 1][j]);
}
if (j) {
cmin(left[i][j], left[i][j - 1]);
cmax(right[i][j], right[i][j - 1]);
}
}
}
}
{
vector<vector<int>> temp(nd, vector<int> (m, -inf));
for (int i = nd - 1; ~i; --i) {
for (int j = m - 1; ~j; --j) {
if (d[i][j] != '#') {
temp[i][j] = i;
if (i + 1 < nd) {
cmax(temp[i][j], temp[i + 1][j]);
}
if (j + 1 < m) {
cmax(temp[i][j], temp[i][j + 1]);
}
}
}
}
for (int i = 0; i < m; ++i) {
bottom[i] = temp[0][i];
}
}
{
vector<vector<int>> temp(nu + 1, vector<int> (m, inf));
for (int i = 0; i <= nu; ++i) {
for (int j = 0; j < m; ++j) {
if (u[i][j] != '#') {
temp[i][j] = i;
if (i) {
cmin(temp[i][j], temp[i - 1][j]);
}
if (j) {
cmin(temp[i][j], temp[i][j - 1]);
}
}
}
}
for (int i = 0; i < m; ++i) {
top[i] = temp[nu][i];
}
}
vector<vector<int>> mp(m, vector<int> (m, inf));
for (int i = 0; i < nd; ++i) {
for (int j = 0; j < m; ++j) {
if (left[i][j] <= right[i][j]) {
cmin(mp[left[i][j]][right[i][j]], i);
}
}
}
for (int l = 0; l < m; ++l) {
for (int r = m - 1; ~r; --r) {
if (l) {
cmin(mp[l][r], mp[l - 1][r]);
}
if (r + 1 < m) {
cmin(mp[l][r], mp[l][r + 1]);
}
}
}
auto meeting_point = [&](int a, int b) {
int p = mp[a][b];
return p <= min(bottom[a], bottom[b]) ? p : inf;
};
vector<int> sum1(nd);
vector<vector<int>> sum2(nd, vector<int> (m));
vector<vector<int>> sum3(nd, vector<int> (m));
vector<vector<int>> sum4(m, vector<int> (m));
for (int i = 0; i < nd; ++i) {
if (i) {
sum1[i] = sum1[i - 1];
for (int j = 0; j < m; ++j) {
sum2[i][j] = sum2[i - 1][j];
sum3[i][j] = sum3[i - 1][j];
}
}
for (int j = 0; j < m; ++j) {
if (left[i][j] <= right[i][j]) {
sum1[i] += d[i][j] - '0';
if (left[i][j]) {
sum2[i][left[i][j] - 1] += d[i][j] - '0';
}
if (right[i][j] + 1 < m) {
sum3[i][right[i][j] + 1] += d[i][j] - '0';
}
if (left[i][j] && right[i][j] + 1 < m) {
sum4[left[i][j] - 1][right[i][j] + 1] += d[i][j] - '0';
}
}
}
}
for (int i = 0; i < nd; ++i) {
for (int j = m - 1; j; --j) {
sum2[i][j - 1] += sum2[i][j];
}
for (int j = 1; j < m; ++j) {
sum3[i][j] += sum3[i][j - 1];
}
}
for (int l = m - 1; ~l; --l) {
for (int r = l; r < m; ++r) {
if (l + 1 < m) {
sum4[l][r] += sum4[l + 1][r];
}
if (r) {
sum4[l][r] += sum4[l][r - 1];
}
if (l + 1 < m && r) {
sum4[l][r] -= sum4[l + 1][r - 1];
}
}
}
auto both_reachable = [&](int a, int b, int l) {
if (meeting_point(a, b) > l) {
return 0;
} else {
return sum1[l] - sum2[l][a] - sum3[l][b] + sum4[a][b];
}
};
vector<int> reachable(m);
for (int i = 0; i < m; ++i) {
reachable[i] = both_reachable(i, i, bottom[i]);
}
vector<vector<int>> event(nu);
vector<bool> ban(m);
for (int i = 0; i < m; ++i) {
if (top[i] >= nu) {
ban[i] = true;
} else {
event[top[i]].push_back(i);
}
}
vector<int> l(m), r(m);
for (int i = m - 1; ~i; --i) {
if (d[0][i] == '#') {
l[i] = inf;
r[i] = -inf;
} else {
l[i] = i;
r[i] = max(i, i + 1 < m ? r[i + 1] : -inf);
}
}
for (int row = nu - 1; ~row; --row) {
for (int i = m - 1; ~i; --i) {
if (u[row][i] == '#') {
l[i] = inf;
r[i] = -inf;
} else if (i + 1 < m) {
cmin(l[i], l[i + 1]);
cmax(r[i], r[i + 1]);
}
}
vector<int> has(m);
vector<int> st(m);
int sum = 0, stl = 0, str = 0, myl = 0, myr = -1;
auto insert = [&](int x) {
if (!ban[x]) {
if (stl < str) {
sum -= has[st[str - 1]];
has[st[str - 1]] -= both_reachable(st[str - 1], x, min(bottom[st[str - 1]], bottom[x]));
sum += has[st[str - 1]];
if (bottom[st[str - 1]] <= bottom[x]) {
--str;
while (stl < str) {
sum -= has[st[str - 1]];
has[st[str - 1]] -= both_reachable(st[str - 1], x, min(bottom[st[str - 1]], bottom[x])) - both_reachable(st[str - 1], x, min(bottom[st[str]], bottom[x]));
sum += has[st[str - 1]];
if (bottom[st[str - 1]] <= bottom[x]) {
--str;
} else {
break;
}
}
}
}
st[str++] = x;
has[x] = reachable[x];
sum += has[x];
}
};
auto erase = [&](int x) {
if (!ban[x]) {
sum -= has[x];
if (stl < str && st[stl] == x) {
++stl;
}
}
};
for (int i = 0; i < m; ++i) {
if (l[i] <= r[i]) {
while (myr < r[i]) {
insert(++myr);
}
while (myl < l[i]) {
erase(myl++);
}
answer += (u[row][i] - '0') * sum;
}
}
for (auto p : event[row]) {
ban[p] = true;
}
}
};
solve(board);
cout << answer << endl;
return 0;
}
Submission Info
Submission Time |
|
Task |
F2 - Reachable Cells |
User |
wxh010910 |
Language |
C++14 (GCC 5.4.1) |
Score |
1500 |
Code Size |
7832 Byte |
Status |
AC |
Exec Time |
6053 ms |
Memory |
41136 KB |
Judge Result
Set Name |
Sample |
All |
Score / Max Score |
0 / 0 |
1500 / 1500 |
Status |
|
|
Set Name |
Test Cases |
Sample |
sample-01.txt, sample-02.txt, sample-03.txt, sample-04.txt |
All |
sample-01.txt, sample-02.txt, sample-03.txt, sample-04.txt, sample-01.txt, sample-02.txt, sample-03.txt, sample-04.txt, subtask01-01.txt, subtask01-02.txt, subtask01-03.txt, subtask01-04.txt, subtask01-05.txt, subtask01-06.txt, subtask01-07.txt, subtask01-08.txt, subtask01-09.txt, subtask01-10.txt, subtask01-11.txt, subtask01-12.txt, subtask01-13.txt, subtask01-14.txt, subtask01-15.txt, subtask01-16.txt, subtask01-17.txt, subtask01-18.txt, subtask01-19.txt, subtask01-20.txt, subtask01-21.txt, subtask01-22.txt, subtask01-23.txt, subtask01-24.txt, subtask01-25.txt, subtask01-26.txt, subtask01-27.txt, subtask01-28.txt |
Case Name |
Status |
Exec Time |
Memory |
sample-01.txt |
AC |
1 ms |
256 KB |
sample-02.txt |
AC |
1 ms |
256 KB |
sample-03.txt |
AC |
1 ms |
256 KB |
sample-04.txt |
AC |
1 ms |
256 KB |
subtask01-01.txt |
AC |
5241 ms |
41040 KB |
subtask01-02.txt |
AC |
5357 ms |
41040 KB |
subtask01-03.txt |
AC |
5752 ms |
41040 KB |
subtask01-04.txt |
AC |
6052 ms |
41040 KB |
subtask01-05.txt |
AC |
5779 ms |
41032 KB |
subtask01-06.txt |
AC |
4406 ms |
41032 KB |
subtask01-07.txt |
AC |
5906 ms |
41040 KB |
subtask01-08.txt |
AC |
5897 ms |
41040 KB |
subtask01-09.txt |
AC |
6034 ms |
41040 KB |
subtask01-10.txt |
AC |
5959 ms |
41040 KB |
subtask01-11.txt |
AC |
5859 ms |
41040 KB |
subtask01-12.txt |
AC |
5683 ms |
41040 KB |
subtask01-13.txt |
AC |
5976 ms |
41040 KB |
subtask01-14.txt |
AC |
6018 ms |
41056 KB |
subtask01-15.txt |
AC |
5223 ms |
41088 KB |
subtask01-16.txt |
AC |
5680 ms |
41064 KB |
subtask01-17.txt |
AC |
5687 ms |
41040 KB |
subtask01-18.txt |
AC |
5379 ms |
41040 KB |
subtask01-19.txt |
AC |
6012 ms |
41136 KB |
subtask01-20.txt |
AC |
5976 ms |
41128 KB |
subtask01-21.txt |
AC |
4854 ms |
41068 KB |
subtask01-22.txt |
AC |
5301 ms |
41084 KB |
subtask01-23.txt |
AC |
5452 ms |
41104 KB |
subtask01-24.txt |
AC |
5189 ms |
41040 KB |
subtask01-25.txt |
AC |
6053 ms |
41088 KB |
subtask01-26.txt |
AC |
6018 ms |
41096 KB |
subtask01-27.txt |
AC |
5970 ms |
41104 KB |
subtask01-28.txt |
AC |
6020 ms |
41108 KB |