Advertisement
SorahISA

F. Fibonacci Grid

Sep 25th, 2024
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.63 KB | Source Code | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define ALL(x) begin(x), end(x)
  5. #define SZ(x) ((int)(x).size())
  6.  
  7. const int INF = INT_MAX >> 2;
  8.  
  9. int main() {
  10.     ios_base::sync_with_stdio(0), cin.tie(0);
  11.    
  12.     int N, M; cin >> N >> M;
  13.    
  14.     vector<string> grid(N);
  15.     for (string &str : grid) cin >> str;
  16.    
  17.     {
  18.         int n_0 = 0;
  19.         for (string &str : grid) n_0 += count(ALL(str), '0');
  20.         if (n_0 == 0 or n_0 == N*M) {
  21.             for (int i = 0; i < N; ++i) for (int j = 0; j < M; ++j) cout << -1 << " \n"[j == M-1];
  22.             return 0;
  23.         }
  24.     }
  25.    
  26.     vector<int> fib{1, 1}, fib_inv(3*M);
  27.     while (fib.back() < 3*M) fib.emplace_back(end(fib)[-1] + end(fib)[-2]);
  28.     for (int i = 0, tok = 1; i < 3*M; ++i) {
  29.         while (fib[tok] <= i) ++tok;
  30.         fib_inv[i] = tok - 1;
  31.     }
  32.    
  33.     vector ans(N, vector<int>(M, -1));
  34.     vector val(N, vector<int>(M));
  35.    
  36.     for (char c0 : {'0', '1'}) for (char c1 : {'0', '1'}) {
  37.        
  38.         string s0(1, c0), s1(1, c1);
  39.         while (SZ(s1) < 3*M) tie(s0, s1) = tuple{s1, s1+s0};
  40.        
  41.         string S = s1 + "#";
  42.         for (int i = 0; i < N; ++i) S += grid[i] + grid[i] + grid[i] + grid[i] + "$";
  43.        
  44.         vector<int> Z(SZ(S), 0);
  45.         for (int i = 1, r = 0, p = 0; i < SZ(S); ++i) {
  46.             if (i < r) Z[i] = min(r-i, Z[i-p]);
  47.             while (i + Z[i] < SZ(S) and S[Z[i]] == S[i + Z[i]]) ++Z[i], ++r, p = i;
  48.             if (i + Z[i] > r) r = i + Z[i], p = i;
  49.         }
  50.        
  51.         for (int i = 0, offset = SZ(s1)+1; i < N; ++i, offset += 4*M+1) {
  52.             if (Z[offset] >= 3*M) {
  53.                 for (int j = 0; j < M; ++j) val[i][j] = INF;
  54.             }
  55.             else {
  56.                 for (int j = 0; j < M; ++j) val[i][j] = fib_inv[Z[offset+j]];
  57.             }
  58.         }
  59.        
  60.         for (int j = 0; j < M; ++j) {
  61.             deque<int> deq_id, deq_val;
  62.             int sz = 0;
  63.             for (int i = 2*N+SZ(fib); i >= 0; --i) {
  64.                 int tmp_val = val[i%N][j] - i;
  65.                 while (SZ(deq_val) and tmp_val < deq_val[sz-1]) deq_id.pop_back(), deq_val.pop_back(), --sz;
  66.                 deq_id.emplace_back(i), deq_val.emplace_back(tmp_val), ++sz;
  67.                
  68.                 if (i < N and grid[i][j] == c0 and grid[(i+1)%N][j] == c1) {
  69.                     int pos = prev(lower_bound(ALL(deq_val), -i)) - begin(deq_val);
  70.                     ans[i][j] = deq_id[pos] - i - 2;
  71.                 }
  72.             }
  73.         }
  74.        
  75.     }
  76.    
  77.     for (int i = 0; i < N; ++i) for (int j = 0; j < M; ++j) cout << ans[i][j] << " \n"[j == M-1];
  78.    
  79.     return 0;
  80. }
  81.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement