結果
問題 | No.1018 suffixsuffixsuffix |
ユーザー |
![]() |
提出日時 | 2020-04-03 23:19:38 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 877 ms / 2,000 ms |
コード長 | 6,626 bytes |
コンパイル時間 | 1,884 ms |
コンパイル使用メモリ | 188,152 KB |
実行使用メモリ | 37,724 KB |
最終ジャッジ日時 | 2024-07-03 06:20:03 |
合計ジャッジ時間 | 11,905 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 34 |
ソースコード
#include <bits/stdc++.h>using namespace std;using lint = long long int;using pint = pair<int, int>;using plint = pair<lint, lint>;struct fast_ios { fast_ios(){ cin.tie(0); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;#define ALL(x) (x).begin(), (x).end()#define FOR(i, begin, end) for(int i=(begin),i##_end_=(end);i<i##_end_;i++)#define IFOR(i, begin, end) for(int i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)#define REP(i, n) FOR(i,0,n)#define IREP(i, n) IFOR(i,0,n)template<typename T> void ndarray(vector<T> &vec, int len) { vec.resize(len); }template<typename T, typename... Args> void ndarray(vector<T> &vec, int len, Args... args) { vec.resize(len); for (auto &v : vec) ndarray(v, args...); }template<typename T> bool chmax(T &m, const T q) { if (m < q) {m = q; return true;} else return false; }template<typename T> bool chmin(T &m, const T q) { if (m > q) {m = q; return true;} else return false; }template<typename T1, typename T2> pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first + r.first, l.second + r.second); }template<typename T1, typename T2> pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first - r.first, l.second - r.second); }template<typename T> istream &operator>>(istream &is, vector<T> &vec){ for (auto &v : vec) is >> v; return is; }template<typename T> ostream &operator<<(ostream &os, const vector<T> &vec){ os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; }template<typename T> ostream &operator<<(ostream &os, const deque<T> &vec){ os << "deq["; for (auto v : vec) os << v << ","; os << "]"; return os; }template<typename T> ostream &operator<<(ostream &os, const set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }template<typename T> ostream &operator<<(ostream &os, const unordered_set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; returnos; }template<typename T> ostream &operator<<(ostream &os, const multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }template<typename T> ostream &operator<<(ostream &os, const unordered_multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}";return os; }template<typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &pa){ os << "(" << pa.first << "," << pa.second << ")"; returnos; }template<typename TK, typename TV> ostream &operator<<(ostream &os, const map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }template<typename TK, typename TV> ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }#define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;// Suffix Array / Longest Common Prefix Array Construction// Comlexity: O(N(log N)^2)template<typename T>struct SuffixArray{T S; // size: Nstd::vector<int> SA; // Suffix Array (size: N + 1, SA[0] == N) SA[i] means S[SA[i]:]std::vector<int> rank; // Rank (inverse of SA) (size: N + 1, rank[N] == 0)std::vector<int> lcp; // Longest Common Prefix Array (size: N) betw. S[SA[i]:] & S[SA[i + 1]:]SuffixArray(const T &str, bool gen_lcp = true) : S(str) {int N = S.size();SA.resize(N + 1);std::iota(SA.begin(), SA.end(), 0);rank.assign(N + 1, -1);for (int i = 0; i < N; i++) rank[i] = S[i];int _ord_mm = 1;auto _comp_suffarr = [&](int i, int j) {if (rank[i] != rank[j])return rank[i] < rank[j];int ri = i + _ord_mm < (int)rank.size() ? rank[i + _ord_mm] : -1;int rj = j + _ord_mm < (int)rank.size() ? rank[j + _ord_mm] : -1;return ri < rj;};std::vector<int> tmp(N + 1);for (_ord_mm = 1; _ord_mm <= N; _ord_mm *= 2) {std::sort(SA.begin(), SA.end(), _comp_suffarr);tmp[SA[0]] = 0;for (int i = 1; i <= N; i++) {tmp[SA[i]] = tmp[SA[i - 1]] + _comp_suffarr(SA[i - 1], SA[i]);}rank = tmp;}if (!gen_lcp) return;lcp.assign(N, 0);int h = 0;for (int i = 0; i < N; i++) {int j = SA[rank[i] - 1];if (h) h--;for (; j + h < N and i + h < N; h++) if (S[j + h] != S[i + h]) break;lcp[rank[i] - 1] = h;}}};// Z algorithm (length of longest common prefix for s[0:N] & s[i:N] for each i)// Complexity: O(N)// <http://snuke.hatenablog.com/entry/2014/12/03/214243>vector<int> z_algorithm(const string &s) {vector<int> ans(s.size());ans[0] = s.size();int i = 1, j = 0;while (i < (int)s.size()) {while (i + j < (int)s.size() && s[j] == s[i + j]) ++j;ans[i] = j;if (!j) {++i;continue;}int k = 1;while (i + k < (int)s.size() && k + ans[k] < j) ans[i + k] = ans[k], ++k;i += k;j -= k;}return ans;}int main(){lint N, M, Q;cin >> N >> M >> Q;string S;cin >> S;if (M < 5) {string T;REP(_, M) T += S;SuffixArray<string> s(T, false);while (Q--) {int k;cin >> k;printf("%d ", s.SA[k] + 1);}puts("");return 0;}auto z = z_algorithm(S);int rec = S.length();REP(i, N) if (i and z[i] + i == N and N % i == 0) chmin(rec, i);// if (S == string(N, S[0])) {// while (Q--) {// lint K;// cin >> K;// printf("%lld ", N * M + 1 - K);// }// puts("");// }S = S.substr(0, rec);M = M * (N / rec);N = rec;string S3 = S + S + S;SuffixArray<string> sa3(S3, false);SuffixArray<string> sa4(S3 + S, false);vector<lint> rnkM(N * 3);REP(i, N * 3) rnkM[i] = sa3.rank[i] + 1LL * (sa4.rank[i + N] - sa3.rank[i]) * (M - 3);map<lint, lint> mp;REP(i, N * 3) mp[rnkM[i]] = N * (M - 3) + i;map<lint, lint> val2pos;REP(i, N) val2pos[rnkM[i]] = i;while (Q--) {lint k;cin >> k;if (mp.count(k)) printf("%lld ", mp[k]);else {lint i = prev(val2pos.upper_bound(k))->second;lint d = k - rnkM[i];printf("%lld ", i + 1 + N * (M - 3 - d));}}}