답안 #585162

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
585162 2022-06-28T11:18:49 Z slime Necklace (Subtask 1-3) (BOI19_necklace1) C++14
85 / 85
347 ms 752 KB
#include "bits/stdc++.h"
using namespace std;
#define int long long
const int MAXN = 3004;
const int MOD = 998244353;
mt19937_64 rng((int)std::chrono::steady_clock::now().time_since_epoch().count());
int rnd(int x, int y) {
  int u = uniform_int_distribution<int>(x, y)(rng); return u;
}
vector<int> prefix_function(string t) {
  int n = t.size();
  vector<int> lps(n);
  lps[0] = 0;
  for(int i=1; i<n; i++) {
    int j = lps[i-1];
    while(j > 0 && t[i] != t[j]) {
      j = lps[j-1];
    }
    if(t[i] == t[j]) lps[i] = j+1;
    else lps[i] = 0;
  }
  return lps;
}
int ans1, sst, tst;
int pows[6010];
int aa[6010], bb[6010];
const int factor = 2017;
int hasha(int l, int r) {
  int qq = aa[l-1] * pows[r - l + 1];
  qq %= MOD;
  int given = aa[r] - qq; 
  if(given < 0) given = (MOD - (abs(given) % MOD)) % MOD;
  else given %= MOD;
  return given;
}
int hashb(int l, int r) {
  int qq = bb[l-1] * pows[r - l + 1];
  qq %= MOD;
  int given = bb[r] - qq; 
  if(given < 0) given = (MOD - (abs(given) % MOD)) % MOD;
  else given %= MOD;
  return given;
}
pair<int, pair<int, int> > lcs(string a, string b) { // length, starting positions
  int n = a.size(), m = b.size();
  a = " " + a;
  b = " " + b;
  int dp[2][m+1];
  for(int i=0; i<2; i++) for(int j=0; j<=m; j++) dp[i][j] = 0;
  int ma = 0;
  for(int i=1; i<=n; i++) {
    for(int j=0; j<=m; j++) dp[i & 1][j] = 0;
    for(int j=1; j<=m; j++) {
      if(a[i] == b[j]) dp[i & 1][j] = dp[(i-1) & 1][j-1] + 1;
      else dp[i & 1][j] = 0;
      ma = max(ma, dp[i & 1][j]);
    }
  }
  aa[0] = bb[0] = 0;
  for(int i=1; i<=n; i++) aa[i] = (aa[i-1] * factor + a[i]) % MOD;
  for(int i=1; i<=m; i++) bb[i] = (bb[i-1] * factor + b[i]) % MOD;
  for(int i=1; i<=n-ma+1; i++) {
    for(int j=1; j<=m-ma+1; j++) {
      if(hasha(i, i+ma-1) == hashb(j, j+ma-1)) {
        return {ma, {i, j} };
      }
    }
  }
  assert(false);
}
void upd_ans(int new_len, int new_sst, int new_tst) {
  if(new_len > ans1) {
    ans1 = new_len;
    sst = new_sst;
    tst = new_tst;
  }
}
void out() {
  cout << ans1 << "\n";
  cout << sst - 1 << " " << tst - 1 << "\n";
}
string reversed(string x) {
  reverse(x.begin(), x.end());
  return x;
}
void solve(int tc) {
  pows[0] = 1;
  for(int i=1; i<6010; i++) pows[i] = (pows[i-1] * factor) % MOD;
  string s, t;
  cin >> s >> t;
  int n = s.size(), m = t.size();
  s = " " + s;
  t = " " + t;
  // Need to compute answer for both t and rev(t), both s and rev(s), for all suffixes of s and t
  // Can't be more duliu

  
  for(int i=2; i<=n; i++) {
    string u;
    u += s.substr(i, n - i + 1);
    u += "?";
    u += t.substr(1, m); // ~ 6000
    vector<int> lpsu = prefix_function(u);
    string v;
    v += reversed(s.substr(1, i-1));
    v += "?";
    v += reversed(t.substr(1, m));
    vector<int> lpsv = prefix_function(v);
    
    for(int j=1; j<m; j++) { // take [1, j]
      // j = 1: n - i + 2
      // j = x: n - i + x + 1 (0 based)
      int suf = lpsu[n-i+j+1];
      int pre = lpsv[i+m-j-1];
      // answer = pre + suf
      int inds = i - pre;
      int indt = j - suf + 1;
      upd_ans(pre + suf, inds, indt);

    }
  }
  reverse(t.begin() + 1, t.end());

  for(int i=2; i<=n; i++) {
    string u;
    u += s.substr(i, n - i + 1);
    u += "?";
    u += t.substr(1, m); // ~ 6000
    vector<int> lpsu = prefix_function(u);
    string v;
    v += reversed(s.substr(1, i-1));
    v += "?";
    v += reversed(t.substr(1, m));
    vector<int> lpsv = prefix_function(v);
    /*
    cout << u << "\n";
    for(int x: lpsu) cout << x << " ";
    cout << "\n";
    cout << v << "\n";
    for(int x: lpsv) cout << x << " ";
    cout << "\n";
    */
    for(int j=1; j<m; j++) { // take [1, j]
      // j = 1: n - i + 2
      // j = x: n - i + x + 1 (0 based)
      int suf = lpsu[n-i+j+1];
      int pre = lpsv[i+m-j-1];
      // answer = pre + suf
      int inds = i - pre;
      int indt = j + pre;
      indt = m - indt + 1;
      upd_ans(pre + suf, inds, indt);

    }
  }

  reverse(t.begin() + 1, t.end());
  
  // Remove whitespace
  s = s.substr(1, n);
  t = t.substr(1, m);
  // Compute lcs of s and t
  pair<int, pair<int, int> > res = lcs(s, t);
  upd_ans(res.first, res.second.first, res.second.second);
  // Compute lcs of s and rev(t)
  reverse(t.begin(), t.end());
  res = lcs(s, t);
  upd_ans(res.first, res.second.first, (int) m - res.second.second - res.first + 2);

  reverse(t.begin(), t.end());
  out();
}
int32_t main() {
  ios::sync_with_stdio(0); cin.tie(0);
  int t = 1; //cin >> t;
  for(int i=1; i<=t; i++) solve(i);
}
// I don't know geometry.
// Teaming is unfair.
/*

zxyabcd
yxbadctz

*/
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 372 KB Output is correct
3 Correct 1 ms 380 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 372 KB Output is correct
3 Correct 1 ms 380 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 6 ms 340 KB Output is correct
7 Correct 5 ms 340 KB Output is correct
8 Correct 6 ms 340 KB Output is correct
9 Correct 6 ms 436 KB Output is correct
10 Correct 8 ms 540 KB Output is correct
11 Correct 5 ms 340 KB Output is correct
12 Correct 7 ms 428 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 372 KB Output is correct
3 Correct 1 ms 380 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 6 ms 340 KB Output is correct
7 Correct 5 ms 340 KB Output is correct
8 Correct 6 ms 340 KB Output is correct
9 Correct 6 ms 436 KB Output is correct
10 Correct 8 ms 540 KB Output is correct
11 Correct 5 ms 340 KB Output is correct
12 Correct 7 ms 428 KB Output is correct
13 Correct 251 ms 540 KB Output is correct
14 Correct 224 ms 516 KB Output is correct
15 Correct 347 ms 624 KB Output is correct
16 Correct 325 ms 752 KB Output is correct
17 Correct 246 ms 624 KB Output is correct
18 Correct 188 ms 588 KB Output is correct
19 Correct 265 ms 636 KB Output is correct
20 Correct 255 ms 748 KB Output is correct
21 Correct 266 ms 524 KB Output is correct