結果
| 問題 |
No.1018 suffixsuffixsuffix
|
| ユーザー |
りあん
|
| 提出日時 | 2020-04-03 22:19:56 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 222 ms / 2,000 ms |
| コード長 | 4,082 bytes |
| コンパイル時間 | 2,445 ms |
| コンパイル使用メモリ | 204,724 KB |
| 最終ジャッジ日時 | 2025-01-09 13:08:28 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 34 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
using P = pair<int, int>;
const int M = 1000000007;
class suffix_array {
// compare (rank[i], rank[i + k]) and (rank[j], rank[j + k])
static bool compare_sa(int n, const vector<int>& rank, int i, int j, int k) {
if (rank[i] != rank[j]) return rank[i] < rank[j];
int ri = i + k <= n ? rank[i + k] : -1;
int rj = j + k <= n ? rank[j + k] : -1;
return ri < rj;
}
public:
static vector<int> construct_sa(const string& s) {
int n = s.size();
vector<int> sa(n + 1), rank(n + 1);
for (int i = 0; i <= n; ++i) {
sa[i] = i;
rank[i] = i < n ? s[i] : -1;
}
for (int k = 1; k <= n; k <<= 1) {
sort(sa.begin(), sa.end(), [&n, &k, &rank](const int& a, const int& b){ return compare_sa(n, rank, a, b, k); });
vector<int> tmp(n + 1);
for (int i = 1; i <= n; ++i)
tmp[sa[i]] = tmp[sa[i - 1]] + compare_sa(n, rank, sa[i - 1], sa[i], k);
for (int i = 0; i <= n; ++i)
rank[i] = tmp[i];
}
return sa;
}
static vector<int> construct_lcp(const string& s, const vector<int>& sa) {
int n = s.length();
vector<int> rank(n + 1), lcp(n + 1);
for (int i = 0; i <= n; ++i) rank[sa[i]] = i;
int h = 0;
for (int i = 0; i < n; ++i) {
if (h > 0) --h;
for (int j = sa[rank[i] - 1]; j + h < n && i + h < n; ++h)
if (s[j + h] != s[i + h]) break;
lcp[rank[i] - 1] = h;
}
return lcp;
}
};
class segtree {
private:
int n, s, t;
vector<int> tr;
const int ex = M;
int q(int k, int l, int r) {
return r <= s || t <= l ? ex : s <= l && r <= t ? tr[k]
: min(q(k << 1 | 1, l, (l + r) >> 1), q((k + 1) << 1, (l + r) >> 1, r));
}
public:
segtree(int m) {
n = 1;
while (n < m) n <<= 1;
tr.clear();
tr.resize((n << 1) - 1, ex);
}
void update(int j, const int& x) {
int i = j + n - 1;
tr[i] = x;
while (i > 0) { i = (i - 1) >> 1; tr[i] = min(tr[i << 1 | 1], tr[(i + 1) << 1]); }
}
// [s, t)
int run(int _s, int _t) { s = _s; t = _t; return q(0, 0, n); }
};
vector<int> kmp(const string& s) {
int n = s.length();
vector<int> res(n + 1);
res[0] = -1;
int j = -1;
for (int i = 0; i < n; ++i) {
while (j >= 0 && s[i] != s[j]) j = res[j];
j++;
res[i + 1] = j;
}
return res;
}
vector<long long> solve(const string& s, long long m, const vector<long long>& qs) {
int n = s.length();
int q = qs.size();
int l = n - kmp(s)[n];
if (l > 0 && l < n && n % l == 0) {
return solve(s.substr(0, l), m * n / l, qs);
}
vector<long long> res(q);
if (m == 1) {
vector<int> sa = suffix_array::construct_sa(s);
for (int i = 0; i < q; ++i) {
res[i] = sa[qs[i]] + 1;
}
}
else {
string t = s + s;
vector<int> sa = suffix_array::construct_sa(t);
long long cnt = 0;
int qi = 0;
for (int i = 1; i <= n * 2; ++i) {
if (sa[i] >= n) {
if (qi < q && cnt + 1 == qs[qi]) {
res[qi] = (m - 2) * n + sa[i] + 1;
++qi;
}
++cnt;
}
else {
while (qi < q && cnt + m - 1 >= qs[qi]) {
res[qi] = (m - (qs[qi] - cnt + 1)) * n + sa[i] + 1;
++qi;
}
cnt += m - 1;
}
}
}
return res;
}
int main() {
cin.tie(0);
ios::sync_with_stdio(0);
int n, q;
long long m;
string s;
cin >> n >> m >> q >> s;
vector<long long> qs(q);
for (int i = 0; i < q; ++i) {
cin >> qs[i];
}
vector<long long> res = solve(s, m, qs);
for (int i = 0; i < q; ++i) {
cout << res[i] << (i < q - 1 ? ' ' : '\n');
}
return 0;
}
りあん