Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- #ifndef d
- #define d(...)
- #endif
- #define st first
- #define nd second
- #define pb push_back
- #define siz(c) (int)(c).size()
- #define all(c) (c).begin(), (c).end()
- typedef long long LL;
- typedef long double LD;
- constexpr int INF=1e9+7;
- constexpr LL INFL=1e18;
- template<class L, class R> ostream &operator<<(ostream &os, pair<L,R> P) {
- return os << "(" << P.st << "," << P.nd << ")";
- }
- template<class T> ostream &operator<<(ostream &os, const vector<T> &V) {
- os << "[";
- for(const auto& x:V)
- os << x << ", ";
- return os << "]";
- }
- constexpr int maxn = 1 << 10;
- int n;
- string M[maxn];
- int pos[maxn][maxn];
- int main()
- {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- string tmp; cin >> tmp;
- n = tmp.size();
- M[0] = tmp;
- for(int i=1; i<n; i++)
- cin >> M[i];
- for(int i=0; i<n; i++) {
- string cur = M[i] + M[i];
- for(size_t j=0; j<cur.size(); j++)
- pos[i][j] = cur[j] - 'a';
- for(int len = 2; len * 2 < n; len <<= 1) {
- vector<pair<pair<int, int>, int>> v;
- for(int j=0; j<cur.size(); j++) {
- v.push_back({{pos[i][j], j + len >= cur.size() ? cur.size() : pos[i][j + len]}, j});
- }
- sort(all(v));
- for(size_t a=0, b=0, cnt=0; a<v.size(); a=b, cnt++) {
- while(b < v.size() and v[a].st == v[b].st)
- pos[i][v[b++].nd] = cnt;
- }
- }
- vector<pair<pair<int, int>, int>> v;
- for(int j=0; j<cur.size()/2; j++) {
- v.push_back({{pos[i][j], pos[i][j + cur.size()/4]}, j});
- }
- sort(all(v));
- for(size_t a=0, b=0, cnt=0; a<v.size(); a=b, cnt++) {
- while(b < v.size() and v[a].st == v[b].st)
- pos[i][v[b++].nd] = cnt;
- }
- for(int j=0; j<n; j++)
- cout << pos[i][j] << " ";
- cout << endl;
- }
- vector<pair<int, int>> cand;
- for(int i=0; i<n; i++) {
- vector<int> cur(n);
- iota(all(cur), 0);
- for(int j=0; j<n; j++) {
- int best = INF;
- vector<int> nxt;
- for(auto k:cur) {
- int x = i + j, y = k;
- if(x >= n) x -= n;
- if(pos[x][y] < best) {
- best = pos[x][y];
- nxt.clear();
- }
- if(pos[x][y] == best)
- nxt.push_back(k);
- }
- cur = nxt;
- }
- assert(not cur.empty());
- cand.emplace_back(i, cur[0]);
- }
- auto get = [&](int x, int y, int add) {
- x += add / n;
- y += add % n;
- if(x >= n) x -= n;
- if(y >= n) y -= n;
- return M[x][y];
- };
- for(int i=0; i<n*n and cand.size() > 1; i++) {
- vector<pair<int, int>> nxt;
- char best = 'z';
- for(auto p:cand) {
- auto c = get(p.st, p.nd, i);
- if(c < best) {
- best = c;
- nxt.clear();
- }
- if(c == best)
- nxt.emplace_back(p);
- }
- }
- int x, y;
- tie(x, y) = cand[0];
- for(int i=0; i<n*n; i++) {
- if(i % n == 0 and i > 0) cout << "\n";
- cout << get(x, y, i);
- }
- cout << "\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement