QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#164482#6844. Suffix Automatonucup-team004WA 1ms3880kbC++206.6kb2023-09-05 01:24:122023-09-05 01:24:13

Judging History

你现在查看的是最新测评结果

  • [2023-09-05 01:24:13]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3880kb
  • [2023-09-05 01:24:12]
  • 提交

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'