제출 #1328440

#제출 시각아이디문제언어결과실행 시간메모리
1328440shahodzSateliti (COCI20_satellti)C++20
110 / 110
418 ms22060 KiB
#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 5;

struct Hashing {
    vector<vector<int> > hs;
    vector<int> PWX, PWY;
    int n, m;
    static const int PX = 3737, PY = 3999, mod = 998244353;

    Hashing() {
    }

    Hashing(vector<string> &s) {
        n = (int) s.size(), m = (int) s[0].size();
        hs.assign(n + 1, vector<int>(m + 1, 0));
        PWX.assign(n + 1, 1);
        PWY.assign(m + 1, 1);
        for (int i = 0; i < n; i++) PWX[i + 1] = 1LL * PWX[i] * PX % mod;
        for (int i = 0; i < m; i++) PWY[i + 1] = 1LL * PWY[i] * PY % mod;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                hs[i + 1][j + 1] = s[i][j] - '*' + 1;
            }
        }
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j < m; j++) {
                hs[i][j + 1] = (hs[i][j + 1] + 1LL * hs[i][j] * PY % mod) % mod;
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j <= m; j++) {
                hs[i + 1][j] = (hs[i + 1][j] + 1LL * hs[i][j] * PX % mod) % mod;
            }
        }
    }

    int get_hash(int x1, int y1, int x2, int y2) {
        // 1-indexed
        assert(1 <= x1 && x1 <= x2 && x2 <= n);
        assert(1 <= y1 && y1 <= y2 && y2 <= m);
        x1--;
        y1--;
        int dx = x2 - x1, dy = y2 - y1;
        return (1LL * (hs[x2][y2] - 1LL * hs[x2][y1] * PWY[dy] % mod + mod) % mod -
                1LL * (hs[x1][y2] - 1LL * hs[x1][y1] * PWY[dy] % mod + mod) % mod * PWX[dx] % mod + mod) % mod;
    }

    int get_hash() {
        return get_hash(1, 1, n, m);
    }
};

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

    int n, m;
    cin >> n >> m;
    vector<string> grid(n);
    for (int i = 0; i < n; i++) {
        cin >> grid[i];
    }

    vector<string> ngrid(2 * n);
    for (int i = 0; i < n; i++) {
        ngrid[i] = grid[i] + grid[i];
        ngrid[i + n] = grid[i] + grid[i];
    }

    Hashing hs(ngrid);

    int row = 0, col = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (i == row && j == col) continue;

            int l = 1, r = n, inc_r = 0, inc_c = 0;
            while (l <= r) {
                int md = (l + r) / 2;
                if (hs.get_hash(i + 1, j + 1, i + md, j + m) == hs.
                    get_hash(row + 1, col + 1, row + md, col + m)) {
                    inc_r = md;
                    l = md + 1;
                } else {
                    r = md - 1;
                }
            }

            if (inc_r == n) continue;

            l = 1, r = m;
            while (l <= r) {
                int md = (l + r) / 2;
                if (hs.get_hash(i + inc_r + 1, j + 1, i + inc_r + 1, j + md) == hs.get_hash(
                        row + inc_r + 1, col + 1, row + inc_r + 1, col + md)) {
                    inc_c = md;
                    l = md + 1;
                } else {
                    r = md - 1;
                }
            }

            if (ngrid[i + inc_r][j + inc_c] < ngrid[row + inc_r][col + inc_c]) {
                row = i;
                col = j;
            }
        }
    }

    for (int i = 0; i < n; i++) {
        cout << ngrid[row + i].substr(col, m) << '\n';
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...