結果
問題 | No.1018 suffixsuffixsuffix |
ユーザー | risujiroh |
提出日時 | 2020-04-04 03:25:37 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 103 ms / 2,000 ms |
コード長 | 2,714 bytes |
コンパイル時間 | 2,214 ms |
コンパイル使用メモリ | 184,744 KB |
実行使用メモリ | 13,488 KB |
最終ジャッジ日時 | 2024-07-03 06:48:54 |
合計ジャッジ時間 | 6,526 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,944 KB |
testcase_02 | AC | 2 ms
6,940 KB |
testcase_03 | AC | 2 ms
6,944 KB |
testcase_04 | AC | 2 ms
6,940 KB |
testcase_05 | AC | 2 ms
6,944 KB |
testcase_06 | AC | 2 ms
6,940 KB |
testcase_07 | AC | 2 ms
6,940 KB |
testcase_08 | AC | 2 ms
6,944 KB |
testcase_09 | AC | 79 ms
12,684 KB |
testcase_10 | AC | 85 ms
12,932 KB |
testcase_11 | AC | 90 ms
13,320 KB |
testcase_12 | AC | 89 ms
12,640 KB |
testcase_13 | AC | 89 ms
12,820 KB |
testcase_14 | AC | 78 ms
12,504 KB |
testcase_15 | AC | 82 ms
12,692 KB |
testcase_16 | AC | 93 ms
13,488 KB |
testcase_17 | AC | 87 ms
12,504 KB |
testcase_18 | AC | 92 ms
12,796 KB |
testcase_19 | AC | 18 ms
6,944 KB |
testcase_20 | AC | 17 ms
6,940 KB |
testcase_21 | AC | 17 ms
6,944 KB |
testcase_22 | AC | 18 ms
6,940 KB |
testcase_23 | AC | 18 ms
6,940 KB |
testcase_24 | AC | 85 ms
12,500 KB |
testcase_25 | AC | 96 ms
13,368 KB |
testcase_26 | AC | 87 ms
12,268 KB |
testcase_27 | AC | 94 ms
12,484 KB |
testcase_28 | AC | 94 ms
12,624 KB |
testcase_29 | AC | 44 ms
10,584 KB |
testcase_30 | AC | 41 ms
10,084 KB |
testcase_31 | AC | 40 ms
10,212 KB |
testcase_32 | AC | 41 ms
10,096 KB |
testcase_33 | AC | 42 ms
10,548 KB |
testcase_34 | AC | 2 ms
6,940 KB |
testcase_35 | AC | 18 ms
6,944 KB |
testcase_36 | AC | 41 ms
10,588 KB |
testcase_37 | AC | 103 ms
13,364 KB |
ソースコード
#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]; } } }