結果
| 問題 |
No.1018 suffixsuffixsuffix
|
| ユーザー |
risujiroh
|
| 提出日時 | 2020-04-04 03:25:37 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.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 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 34 |
ソースコード
#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];
}
}
}
risujiroh