Submission #369518

#TimeUsernameProblemLanguageResultExecution timeMemory
369518wleung_bvgSateliti (COCI20_satellti)C++17
110 / 110
626 ms60104 KiB
#include <bits/stdc++.h> using namespace std; template <class C> constexpr int sz(const C &c) { return int(c.size()); } constexpr const char nl = '\n', sp = ' '; using uint = unsigned int; using ll = long long; using ull = unsigned long long; using ld = long double; #if __SIZEOF_INT128__ using i128 = __int128_t; using ui128 = __uint128_t; #endif template <class _T> struct SAISSuffixArray { using T = _T; static vector<int> SAIS(const vector<int> &S) { if (S.empty()) return vector<int>(); int N = S.size(), K = *max_element(S.begin(), S.end()) + 1; vector<bool> isL(N + 1, false); vector<int> ind(N), cnt(K + 1, 0), lms; lms.reserve(N); for (auto &&a : S) cnt[a + 1]++; partial_sum(cnt.begin(), cnt.end(), cnt.begin()); isL[N - 1] = true; for (int i = N - 2; i >= 0; i--) isL[i] = S[i] == S[i + 1] ? isL[i + 1] : S[i] > S[i + 1]; auto c = [&] (int i) { return i > 0 && !isL[i] && isL[i - 1]; }; for (int i = 1; i < N; i++) if (c(i)) lms.push_back(i); auto IS = [&] { vector<int> tmp(cnt.begin() + 1, cnt.end()); fill(ind.begin(), ind.end(), -1); for (int i = int(lms.size()) - 1; i >= 0; i--) ind[--tmp[S[lms[i]]]] = lms[i]; tmp = vector<int>(cnt.begin(), cnt.end() - 1); for (int i = -1, j; i < N; i++) if ((j = i < 0 ? N - 1 : ind[i] - 1) >= 0 && isL[j]) ind[tmp[S[j]]++] = j; tmp = vector<int>(cnt.begin() + 1, cnt.end()); for (int i = N - 1, j; i >= 0; i--) if ((j = ind[i] - 1) >= 0 && !isL[j]) ind[--tmp[S[j]]] = j; }; if (int(lms.size()) > 1) { IS(); vector<int> tmp(ind.begin(), ind.end()); for (int i = 0, j = 0, a = -1; i < N; i++) if (c(tmp[i])) { for (int b = tmp[i]; a >= 0 && S[a] == S[b];) { a++; b++; if (c(a) || c(b)) { j -= int(c(a) && c(b)); break; } } ind[a = tmp[i]] = ++j; } tmp = vector<int>(lms.size()); for (int i = 0; i < int(tmp.size()); i++) tmp[i] = ind[lms[i]]; tmp = SAIS(tmp); for (int i = 0; i < int(tmp.size()); i++) tmp[i] = lms[tmp[i]]; lms = tmp; } IS(); return ind; } static vector<int> init(const vector<T> &S) { if (S.empty()) return vector<int>(); T offset = *min_element(S.begin(), S.end()); vector<int> A(S.size()); for (int i = 0; i < int(S.size()); i++) A[i] = S[i] - offset; return A; } int N; vector<T> S; vector<int> ind, rnk, LCP; template <class F> SAISSuffixArray(int N, F f) : N(N) { S.reserve(N); for (int i = 0; i < N; i++) S.push_back(f()); ind = SAIS(init(S)); rnk.resize(N); LCP.resize(N); for (int i = 0; i < N; i++) rnk[ind[i]] = i; for (int i = 0, k = 0; i < N; i++) { if (rnk[i] == N - 1) { LCP[rnk[i]] = k = 0; continue; } int j = ind[rnk[i] + 1]; while (i + k < N && j + k < N && S[i + k] == S[j + k]) k++; if ((LCP[rnk[i]] = k) > 0) k--; } } template <class It> SAISSuffixArray(It st, It en) : SAISSuffixArray(en - st, [&] { return *st++; }) {} }; template <class It> It minRotation(It st, It en) { int N = en - st, i = 0; auto ind = [&] (int i) { return i < N ? i : i - N; }; for (int j = 0; j < N; j++) for (int k = 0; k < N; k++) { auto &a = st[ind(i + k)], &b = st[ind(j + k)]; if (i + k == j || a < b) { j += max(0, k - 1); break; } if (a > b) { i = j; break; } } return st + i; } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // freopen("err.txt", "w", stderr); ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int N, M; cin >> N >> M; vector<string> A(N); for (auto &&a : A) cin >> a; vector<vector<int>> rnk(N, vector<int>(M)), ind = rnk; string S = ""; S.reserve(N * M * 2); for (int i = 0; i < N; i++) { S.insert(S.end(), A[i].begin(), A[i].end()); S.insert(S.end(), A[i].begin(), A[i].end()); } SAISSuffixArray<char> SA(S.begin(), S.end()); vector<int> sInd(SA.N), r(SA.N); for (int i = 0; i < SA.N; i++) { if (i != 0 && SA.LCP[i - 1] >= M) sInd[i] = sInd[i - 1]; else sInd[i] = i; } for (int i = 0; i < SA.N; i++) r[i] = sInd[SA.rnk[i]]; for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) { rnk[i][j] = r[i * M * 2 + j]; ind[i][SA.ind[SA.rnk[i * M * 2 + j]] % M] = i * M + j; } vector<pair<vector<int>, int>> rot(M); for (int j = 0; j < M; j++) { vector<int> col(N); for (int i = 0; i < N; i++) col[i] = rnk[i][j]; auto it = minRotation(col.begin(), col.end()); int i = it - col.begin(); rotate(col.begin(), it, col.end()); rot[j] = make_pair(col, ind[i][j]); } sort(rot.begin(), rot.end()); int i = rot[0].second / M, j = rot[0].second % M; rotate(A.begin(), A.begin() + i, A.end()); for (int k = 0; k < N; k++) { rotate(A[k].begin(), A[k].begin() + j, A[k].end()); cout << A[k] << nl; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...