Submission #403107

# Submission time Handle Problem Language Result Execution time Memory
403107 2021-05-12T18:41:57 Z rama_pang Necklace (Subtask 1-3) (BOI19_necklace1) C++17
0 / 85
7 ms 308 KB
#include <bits/stdc++.h>
using namespace std;

class HashString {
 public:
  const int KEY = 37;
  const int MOD = 1e9 + 9;

  int N;
  string S;
  vector<int> H;

  vector<int> power;
  vector<int> inv_power;

  HashString(string S) : S(S) {
    N = S.size();
    H.resize(N);
    power.resize(N);
    inv_power.resize(N);

    const auto Power = [&](int a, int x) {
      int z = 1;
      while (x) {
        if (x & 1) z = 1ll * z * a % MOD;
        x /= 2;
        a = 1ll * a * a % MOD;
      }
      return z;
    };

    power[0] = inv_power[0] = 1;
    power[1] = KEY;
    inv_power[1] = Power(KEY, MOD - 2);
    for (int i = 2; i < N; i++) {
      power[i] = 1ll * KEY * power[i - 1] % MOD;
      inv_power[i] = 1ll * inv_power[i - 1] * inv_power[1] % MOD;
    }

    for (int i = 0; i < N; i++) {
      assert(1ll * power[i] * inv_power[i] % MOD == 1);
    }

    for (int i = 0; i < N; i++) {
      H[i] = ((i > 0 ? H[i - 1] : 0) + 1ll * (S[i] - 'a' + 1) * power[i]) % MOD;
    }
  }

  int GetHash(int L, int R) {
    int res = (H[R] + MOD - (L > 0 ? H[L - 1] : 0)) % MOD;
    return 1ll * res * inv_power[L] % MOD;
  }
};

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

  string S, T;
  cin >> S >> T;

  const auto Solve = [&]() -> array<int, 3> {
    int N = S.size();
    int M = T.size();

    array<int, 3> ans = {0, 0, 0};
    HashString HS = HashString(S);
    HashString HT = HashString(T);

    // cout << HS.GetHash(2, 3) << ' ' << HT.GetHash(1, 2) << " hm\n";

    for (int t = 0; t < M; t++) {
      vector<int> dp(N);
      // dp[s] = longest suffix of T[0...t-1] which is a prefix of S[s...N]
      for (int s = 0; s < N; s++) {
        int lo = 0, hi = max(N, M);
        while (lo < hi) {
          int md = (lo + hi + 1) / 2;
          if (0 <= s - md + 1 && 0 <= t - md &&
              HS.GetHash(s - md + 1, s) == HT.GetHash(t - md, t - 1)) {
            lo = md;
          } else {
            hi = md - 1;
          }
        }
        // cout << s << ' ' << t << ' ' << lo << " getdp\n"; 
        dp[s - lo + 1] = max(dp[s - lo + 1], lo);
      }
      for (int s = 1; s < N; s++) {
        dp[s] = max(dp[s], dp[s - 1] - 1);
      }

      // cout << "DP: ";
      // for (int s = 0; s < N; s++) {
      //   cout << dp[s] << ' ';
      // }
      // cout << '\n';

      for (int s = 0; s < N; s++) {
        // Get longest common prefix starting with S[s...N], T[t...M]
        int lo = 0, hi = max(N, M);
        while (lo < hi) {
          int md = (lo + hi + 1) / 2;
          if (s + md <= N && t + md <= M &&
              HS.GetHash(s, s + md - 1) == HT.GetHash(t, t + md - 1)) {
            lo = md;
          } else {
            hi = md - 1;
          }
        }

        // S[s...s + lo - 1] == T[t...t + lo - 1]
        // Then, answer is lo + dp[s + lo]
        int len = lo + dp[s + lo];
        ans = max(ans, {len, s, t - dp[s + lo]});

        // cout << s << ' ' << t << ' ' << lo << ' ' << dp[s + lo] << " ha\n";
      }
    }

    return ans;
  };

  auto ans1 = Solve();
  reverse(begin(T), end(T));
  auto ans2 = Solve();
  ans2[2] = int(T.size()) - ans2[2] - ans2[0];
  auto ans = max(ans1, ans2);

  // auto ans = Solve();

  cout << ans[0] << '\n' << ans[1] << ' ' << ans[2] << '\n';
  return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 7 ms 204 KB Output is correct
2 Correct 7 ms 308 KB Output is correct
3 Correct 6 ms 204 KB Output is correct
4 Correct 6 ms 204 KB Output is correct
5 Incorrect 6 ms 204 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 7 ms 204 KB Output is correct
2 Correct 7 ms 308 KB Output is correct
3 Correct 6 ms 204 KB Output is correct
4 Correct 6 ms 204 KB Output is correct
5 Incorrect 6 ms 204 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 7 ms 204 KB Output is correct
2 Correct 7 ms 308 KB Output is correct
3 Correct 6 ms 204 KB Output is correct
4 Correct 6 ms 204 KB Output is correct
5 Incorrect 6 ms 204 KB Output isn't correct