結果

問題 No.1018 suffixsuffixsuffix
ユーザー risujirohrisujiroh
提出日時 2020-04-04 03:25:37
言語 C++14
(gcc 13.2.0 + boost 1.83.0)
結果
AC  
実行時間 108 ms / 2,000 ms
コード長 2,714 bytes
コンパイル時間 1,991 ms
コンパイル使用メモリ 182,144 KB
実行使用メモリ 13,496 KB
最終ジャッジ日時 2023-09-16 05:17:45
合計ジャッジ時間 7,571 ms
ジャッジサーバーID
(参考情報)
judge14 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,380 KB
testcase_01 AC 1 ms
4,376 KB
testcase_02 AC 2 ms
4,380 KB
testcase_03 AC 2 ms
4,376 KB
testcase_04 AC 1 ms
4,376 KB
testcase_05 AC 2 ms
4,380 KB
testcase_06 AC 2 ms
4,380 KB
testcase_07 AC 2 ms
4,376 KB
testcase_08 AC 1 ms
4,380 KB
testcase_09 AC 84 ms
12,556 KB
testcase_10 AC 88 ms
12,732 KB
testcase_11 AC 96 ms
13,424 KB
testcase_12 AC 94 ms
12,784 KB
testcase_13 AC 96 ms
12,632 KB
testcase_14 AC 83 ms
12,532 KB
testcase_15 AC 87 ms
12,788 KB
testcase_16 AC 97 ms
13,356 KB
testcase_17 AC 93 ms
12,436 KB
testcase_18 AC 95 ms
12,656 KB
testcase_19 AC 19 ms
4,376 KB
testcase_20 AC 19 ms
4,380 KB
testcase_21 AC 19 ms
4,380 KB
testcase_22 AC 19 ms
4,376 KB
testcase_23 AC 20 ms
4,380 KB
testcase_24 AC 90 ms
12,528 KB
testcase_25 AC 102 ms
13,496 KB
testcase_26 AC 92 ms
12,376 KB
testcase_27 AC 99 ms
12,464 KB
testcase_28 AC 98 ms
12,496 KB
testcase_29 AC 44 ms
10,548 KB
testcase_30 AC 43 ms
10,088 KB
testcase_31 AC 43 ms
9,868 KB
testcase_32 AC 44 ms
10,140 KB
testcase_33 AC 44 ms
10,480 KB
testcase_34 AC 2 ms
4,380 KB
testcase_35 AC 20 ms
4,380 KB
testcase_36 AC 43 ms
10,468 KB
testcase_37 AC 108 ms
13,356 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

template <class T> struct sparse_table {
  vector<vector<T>> t;
  sparse_table(const vector<T>& v = {}) : t{v} {
    for (int k = 1, n = v.size(); 1 << k <= n; ++k) {
      t.emplace_back(n - (1 << k) + 1);
      for (int i = 0; i + (1 << k) <= n; ++i)
        t[k][i] = min(t[k - 1][i], t[k - 1][i + (1 << (k - 1))]);
    }
  }
  T fold(int l, int r) const {
    assert(l < r);
    int k = __lg(r - l);
    return min(t[k][l], t[k][r - (1 << k)]);
  }
};

template <class S> vector<int> build_sa(const S& s) {
  int n = s.size();
  vector<int> sa(n), id(begin(s), end(s)), buf(n);
  iota(rbegin(sa), rend(sa), 0);
  stable_sort(begin(sa), end(sa), [&](int i, int j) { return s[i] < s[j]; });
  for (int m = 1; m < n; m *= 2) {
    for (int k = 0; k < n; ++k) {
      int i = sa[k], p = k ? sa[k - 1] : n, j = i + m / 2, q = p + m / 2;
      buf[i] = p + m < n and id[i] == id[p] and id[j] == id[q] ? buf[p] : k;
    }
    swap(id, buf);
    iota(begin(buf), end(buf), 0);
    auto nsa = sa;
    for (int k = 0, i; k < n; ++k)
      if ((i = sa[k] - m) >= 0) nsa[buf[id[i]]++] = i;
    swap(sa, nsa);
  }
  return sa;
}

template <class S> struct suffix_array {
  const S s;
  const int n;
  vector<int> sa, rank, h;
  suffix_array(const S& _s = S()) : s(_s), n(s.size()), rank(n), h(n) {
    sa = build_sa(s);
    for (int k = 0; k < n; ++k) rank[sa[k]] = k;
    for (int i = 0, m = 0; i < n; ++i, m = max(m - 1, 0)) {
      int j = rank[i] + 1 < n ? sa[rank[i] + 1] : n;
      while (max(i, j) + m < n and s[i + m] == s[j + m]) ++m;
      h[rank[i]] = m;
    }
  }
  int lcp(int i, int j) const {
    static sparse_table<int> st(h);
    if (i == j) return n - i;
    if (rank[i] > rank[j]) swap(i, j);
    return st.fold(rank[i], rank[j]);
  }
  int cmp(int i, int j, int len) const {
    int m = lcp(i, j);
    return m < len ? s[i + m] - s[j + m] : 0;
  }
};

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n, q;
  long long m;
  cin >> n >> m >> q;
  string s;
  cin >> s;
  {
    suffix_array<string> sa(s);
    for (int d = 1; d < n; ++d) {
      if (n % d == 0 and sa.cmp(0, d, n - d) == 0) {
        m *= n / d;
        n = d;
        s.erase(begin(s) + n, end(s));
        break;
      }
    }
  }
  auto sa = build_sa(s + s);
  auto len = [&](int p) {
    return sa[p] < n ? m - 1 : 1;
  };
  int p = 0;
  long long offset = 0;
  while (q--) {
    long long k;
    cin >> k;
    --k;
    while (k >= offset + len(p)) {
      offset += len(p);
      ++p;
    }
    if (sa[p] < n) {
      cout << sa[p] + n * (m - 2 - (k - offset)) + 1 << " \n"[q == 0];
    } else {
      cout << sa[p] + n * (m - 2) + 1 << " \n"[q == 0];
    }
  }
}
0