Submission #1302090

#TimeUsernameProblemLanguageResultExecution timeMemory
1302090uranium235Nafta (COI15_nafta)C++17
100 / 100
261 ms31976 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

template <class a, class b> ostream& operator<<(ostream &l, const pair<a, b> &r) {
    l << "(" << r.first << ", " << r.second << ")";
    return l;
}

template <class t, unsigned long int s> ostream& operator<<(ostream &l, const array<t, s> &r) {
    l << "[";
    for (int i = 0; i + 1 < s; i++) l << r[i] << ", ";
    if (s > 0) l << r[s - 1];
    l << "]";
    return l;
}

template <class t> ostream& operator<<(ostream &l, const vector<t> &r) {
    l << "{";
    for (int i = 0; i + 1 < r.size(); i++) l << r[i] << ", ";
    if (!r.empty()) l << r.back();
    l << "}";
    return l;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, m;
    cin >> n >> m;

    vector<vector<int>> a(n, vector<int>(m));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            char c;
            cin >> c;
            a[i][j] = c == '.' ? -1 : (c - '0');
        }
    }

    vector<vector<int>> ints(m + 1, vector<int>(m + 1));
    array<array<int, 2>, 4> del{{ {0, 1}, {0, -1}, {1, 0}, {-1, 0} }};
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (a[i][j] == -1) continue;

            array<int, 3> x{{ j, j, 0 }};
            queue<pair<int, int>> q;
            q.push({i, j});
            while (!q.empty()) {
                pair<int, int> p = q.front();
                q.pop();
                if (a[p.first][p.second] == -1) continue;
                x[0] = min(x[0], p.second);
                x[1] = max(x[1], p.second);
                x[2] += a[p.first][p.second];
                a[p.first][p.second] = -1;

                for (auto [dx, dy] : del) {
                    dx += p.first;
                    dy += p.second;
                    if (dx < 0 || dx >= n || dy < 0 || dy >= m) continue;

                    q.push({dx, dy});
                }
            }

            ints[x[0]][x[1]] += x[2];
        }
    }

    for (int i = n - 1; i >= 0; i--) {
        for (int j = m - 1; j >= 0; j--) {
            ints[i][j] += ints[i + 1][j] + ints[i][j + 1] - ints[i + 1][j + 1];
        }
    }

    auto cost = [&](int l, int r) -> int {
        // count starts at or after l, ends at or after r
        // overcounts those who start and end after r  
        return ints[l][r] - ints[r + 1][r + 1];
    };

    vector<int> dp(m + 1), pd(m + 1);
    auto dnc = [&](int l, int r, int ql, int qr, auto &&self) -> void {
        int m = (l + r) / 2;
        pair<int, int> cur;
        for (int i = ql; i <= min(qr, m); i++) {
            cur = max(cur, { dp[i] + cost(i, m), i });
        }
        pd[m + 1] = cur.first;
        if (l == r) return;
        self(l, m, ql, cur.second, self);
        self(m + 1, r, cur.second, qr, self);
    };
    for (int i = 0; i < m; i++) {
        fill(pd.begin(), pd.end(), 0);
        dnc(0, m - 1, 0, m - 1, dnc);
        int mx = 0;
        for (int i : pd) mx = max(mx, i);
        cout << mx << '\n';
        swap(dp, pd);
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...