Submission #1137871

#TimeUsernameProblemLanguageResultExecution timeMemory
1137871eysbutnoSateliti (COCI20_satellti)C++20
50 / 110
605 ms588548 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using pii = array<int, 2>;

#define all(x) begin(x), end(x)
#define sz(x) (int) (x).size()

constexpr int M = 1e9 + 9;
constexpr int B = 137;
constexpr int LG = 12;

using Info = array<ll, LG>;

mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

int main() {
    cin.tie(0) -> sync_with_stdio(0);
    int n, m;
    cin >> n >> m;
    vector grid(2 * n, vector<int>(2 * m));
    array<int, 2> vals = {
        uniform_int_distribution<int>(0, B - 1)(rng),
        uniform_int_distribution<int>(0, B - 1)(rng)
    };
    if (vals[0] < vals[1]) { swap(vals[0], vals[1]); }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            char c;
            cin >> c;
            int v = vals[(c == '*')];
            grid[i][j] = v;
            grid[i + n][j] = v;
            grid[i][j + m] = v;
            grid[i + n][j + m] = v;
        }
    }

    vector<ll> pows(n * m + 1);
    pows[0] = 1;
    for (int i = 1; i <= n * m; i++) {
        pows[i] = (pows[i - 1] * B) % M;
    }

    vector lr(2 * n, vector<Info>(m));
    vector lc(2 * n, vector<Info>(2 * m));

    int row = n - 1, col = m - 1;
    for (int i = 2 * n - 1; i >= 0; i--) {
        for (int j = 2 * m - 1; j >= 0; j--) {
            lc[i][j][0] = grid[i][j];
            for (int k = 1; k < LG; k++) {
                if (j + (1 << k) > 2 * m) { break; }
                const int nxt = j + (1 << (k - 1));
                lc[i][j][k] = (lc[i][j][k - 1] + pows[1 << (k - 1)] * lc[i][nxt][k - 1]) % M;
            } 
        }

        ll cur = 0;
        for (int j = 2 * m - 1; j >= m; j--) {
            cur = (cur * B + grid[i][j]) % M;
        }

        for (int j = m - 1; j >= 0; j--) {
            cur -= pows[m - 1] * grid[i][j + m] % M;
            (cur += M) %= M;
            cur = (cur * B + grid[i][j]) % M;
            lr[i][j][0] = cur;
            for (int k = 1; k < LG; k++) {
                if (i + (1 << k) > 2 * n) { continue; }
                const int nxt = i + (1 << (k - 1));
                lr[i][j][k] = (lr[i][j][k - 1] + pows[1 << (k - 1)] * lr[nxt][j][k - 1]) % M;
            }
        }

        if (i >= n) { continue; }

        for (int j = 0; j < m; j++) {
            int diff = 0;
            for (int k = LG - 1; k >= 0; k--) {
                if (diff + (1 << k) > n) { continue; }
                if (lr[row + diff][col][k] == lr[i + diff][j][k]) {
                    diff += (1 << k);
                }
            }

            if (diff == n) {
                continue;
            }

            int diff2 = 0;
            for (int k = LG - 1; k >= 0; k--) {
                if (diff2 + (1 << k) > m) { continue; }
                if (lc[row + diff][col + diff2][k] == lc[i + diff][j + diff2][k]) {
                    diff2 += (1 << k);
                }
            }

            if (grid[i + diff][j + diff2] < grid[row + diff][col + diff2]) {
                row = i, col = j;
            }
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            int v = grid[row + i][col + j];
            cout << (vals[0] == v ? '.' : '*');
        }
        cout << "\n";
    }

    /*

    cout << lr[1][4][1] << " " << lr[0][0][1] << "\n";

    cout << lr[1][4][0] << " " << lr[2][4][0] << "\n";
    cout << lr[0][0][0] << " " << lr[1][0][0] << "\n";

    cout << (lr[1][4][0] + B * lr[2][4][0]) % M << "\n";
    cout << (lr[0][0][0] + B * lr[1][0][0]) % M << "\n";
    */
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...