QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#164482 | #6844. Suffix Automaton | ucup-team004 | WA | 1ms | 3880kb | C++20 | 6.6kb | 2023-09-05 01:24:12 | 2023-09-05 01:24:13 |
Judging History
answer
#include <bits/stdc++.h>
using i64 = long long;
template<class T,
class Cmp = std::less<T>>
struct RMQ {
const Cmp cmp = Cmp();
static constexpr unsigned B = 64;
using u64 = unsigned long long;
int n;
std::vector<std::vector<T>> a;
std::vector<T> pre, suf, ini;
std::vector<u64> stk;
RMQ() {}
RMQ(const std::vector<T> &v) {
init(v);
}
void init(const std::vector<T> &v) {
n = v.size();
pre = suf = ini = v;
stk.resize(n);
if (!n) {
return;
}
const int M = (n - 1) / B + 1;
const int lg = std::__lg(M);
a.assign(lg + 1, std::vector<T>(M));
for (int i = 0; i < M; i++) {
a[0][i] = v[i * B];
for (int j = 1; j < B && i * B + j < n; j++) {
a[0][i] = std::min(a[0][i], v[i * B + j], cmp);
}
}
for (int i = 1; i < n; i++) {
if (i % B) {
pre[i] = std::min(pre[i], pre[i - 1], cmp);
}
}
for (int i = n - 2; i >= 0; i--) {
if (i % B != B - 1) {
suf[i] = std::min(suf[i], suf[i + 1], cmp);
}
}
for (int j = 0; j < lg; j++) {
for (int i = 0; i + (2 << j) <= M; i++) {
a[j + 1][i] = std::min(a[j][i], a[j][i + (1 << j)], cmp);
}
}
for (int i = 0; i < M; i++) {
const int l = i * B;
const int r = std::min(1U * n, l + B);
u64 s = 0;
for (int j = l; j < r; j++) {
while (s && cmp(v[j], v[std::__lg(s) + l])) {
s ^= 1ULL << std::__lg(s);
}
s |= 1ULL << (j - l);
stk[j] = s;
}
}
}
T operator()(int l, int r) {
if (l / B != (r - 1) / B) {
T ans = std::min(suf[l], pre[r - 1], cmp);
l = l / B + 1;
r = r / B;
if (l < r) {
int k = std::__lg(r - l);
ans = std::min({ans, a[k][l], a[k][r - (1 << k)]}, cmp);
}
return ans;
} else {
int x = B * (l / B);
return ini[__builtin_ctzll(stk[r - 1] >> (l - x)) + l];
}
}
};
struct SuffixArray {
int n;
std::vector<int> sa, rk, lc;
SuffixArray(const std::string &s) {
n = s.length();
sa.resize(n);
lc.resize(n - 1);
rk.resize(n);
std::iota(sa.begin(), sa.end(), 0);
std::sort(sa.begin(), sa.end(), [&](int a, int b) {return s[a] < s[b];});
rk[sa[0]] = 0;
for (int i = 1; i < n; ++i)
rk[sa[i]] = rk[sa[i - 1]] + (s[sa[i]] != s[sa[i - 1]]);
int k = 1;
std::vector<int> tmp, cnt(n);
tmp.reserve(n);
while (rk[sa[n - 1]] < n - 1) {
tmp.clear();
for (int i = 0; i < k; ++i)
tmp.push_back(n - k + i);
for (auto i : sa)
if (i >= k)
tmp.push_back(i - k);
std::fill(cnt.begin(), cnt.end(), 0);
for (int i = 0; i < n; ++i)
++cnt[rk[i]];
for (int i = 1; i < n; ++i)
cnt[i] += cnt[i - 1];
for (int i = n - 1; i >= 0; --i)
sa[--cnt[rk[tmp[i]]]] = tmp[i];
std::swap(rk, tmp);
rk[sa[0]] = 0;
for (int i = 1; i < n; ++i)
rk[sa[i]] = rk[sa[i - 1]] + (tmp[sa[i - 1]] < tmp[sa[i]] || sa[i - 1] + k == n || tmp[sa[i - 1] + k] < tmp[sa[i] + k]);
k *= 2;
}
for (int i = 0, j = 0; i < n; ++i) {
if (rk[i] == 0) {
j = 0;
} else {
for (j -= j > 0; i + j < n && sa[rk[i] - 1] + j < n && s[i + j] == s[sa[rk[i] - 1] + j]; )
++j;
lc[rk[i] - 1] = j;
}
}
}
};
template <typename T>
struct Fenwick {
int n;
std::vector<T> a;
Fenwick(int n = 0) {
init(n);
}
void init(int n) {
this->n = n;
a.assign(n, T());
}
void add(int x, T v) {
for (int i = x + 1; i <= n; i += i & -i) {
a[i - 1] += v;
}
}
T sum(int x) {
auto ans = T();
for (int i = x; i > 0; i -= i & -i) {
ans += a[i - 1];
}
return ans;
}
T rangeSum(int l, int r) {
return sum(r) - sum(l);
}
int kth(T k) {
int x = 0;
for (int i = 1 << std::__lg(n); i; i /= 2) {
if (x + i <= n && k >= a[x + i - 1]) {
x += i;
k -= a[x - 1];
}
}
return x;
}
};
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::string s;
std::cin >> s;
SuffixArray sa(s);
const int n = s.size();
std::vector<int> cnt(n + 1);
for (int i = 0; i < n; i++) {
int len = n - sa.sa[i];
int lcp = 0;
if (i > 0) {
lcp = sa.lc[i - 1];
}
cnt[lcp + 1]++;
if (len < n) {
cnt[len + 1]--;
}
}
for (int i = 1; i <= n; i++) {
cnt[i] += cnt[i - 1];
}
std::vector<i64> pre(n + 1);
for (int i = 1; i <= n; i++) {
pre[i] = pre[i - 1] + cnt[i];
}
int Q;
std::cin >> Q;
std::vector<std::pair<int, int>> ans(Q);
std::vector<std::vector<std::pair<int, int>>> qry(n + 1);
for (int i = 0; i < Q; i++) {
i64 k;
std::cin >> k;
k--;
if (k >= pre[n]) {
ans[i] = {-1, -1};
continue;
}
int len = std::upper_bound(pre.begin(), pre.end(), k) - pre.begin();
k -= pre[len - 1];
qry[len].push_back({k, i});
}
Fenwick<int> fen(n);
std::vector<std::vector<int>> add(n + 1);
for (int i = 0; i < n; i++) {
int len = n - sa.sa[i];
int lcp = 0;
if (i > 0) {
lcp = sa.lc[i - 1];
}
add[lcp + 1].push_back(i);
}
for (int l = 1; l <= n; l++) {
for (auto i : add[l]) {
fen.add(i, 1);
}
for (auto [k, i] : qry[l]) {
int v = fen.kth(k);
v = sa.sa[v];
ans[i] = {v + 1, v + l};
}
fen.add(sa.rk[n - l], -1);
}
for (auto [x, y] : ans) {
std::cout << x << " " << y << "\n";
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3564kb
input:
ccpcguilin 5 1 10 4 8 26
output:
1 1 2 3 8 8 1 2 4 7
result:
ok 5 lines
Test #2:
score: 0
Accepted
time: 1ms
memory: 3504kb
input:
banana 3 5 10 16
output:
1 2 2 5 -1 -1
result:
ok 3 lines
Test #3:
score: -100
Wrong Answer
time: 1ms
memory: 3880kb
input:
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr 1000 752 397 968 637 706 758 780 574 1032 599 431 1038 700 868 252 1084 813 277 565 112 69 997 222 897 931 75 200 360 698 196 31 971 1064 591 485 179 528 71 45 422 272 925 8 197 796 116 187 983 1057 939 ...
output:
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 28 96 -1 -1 -1 -1 -1 -1 -1 -1 22 96 -1 -1 -1 -1 -1 -1 -1 -1 66 96 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 26 96 52 96 -1 -1 -1 -1 -1 -1 89 96 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ...
result:
wrong answer 21st lines differ - expected: '1 69', found: '28 96'