求助
查看原帖
求助
764666
LostKeyToReach楼主2024/8/25 19:00

赛时的代码,爆零了。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 300005;
int n, q, sa[N], rk[N], h[N], a[N], st[N][20];
char s[N];
void build_sa() {
    vector<int> cnt(max(n, 256)), x(n), y(n);
    for (int i = 0; i < n; ++i) cnt[x[i] = s[i]]++;
    for (int i = 1; i < 256; ++i) cnt[i] += cnt[i - 1];
    for (int i = n - 1; i >= 0; --i) sa[--cnt[x[i]]] = i;
    for (int len = 1, p = 0; p < n && len < n; len <<= 1) {
        p = 0;
        for (int i = n - len; i < n; ++i) y[p++] = i;
        for (int i = 0; i < n; ++i) if (sa[i] >= len) y[p++] = sa[i] - len;
        fill(cnt.begin(), cnt.begin() + p, 0);
        for (int i = 0; i < n; ++i) cnt[x[y[i]]]++;
        for (int i = 1; i < p; ++i) cnt[i] += cnt[i - 1];
        for (int i = n - 1; i >= 0; --i) sa[--cnt[x[y[i]]]] = y[i];
        swap(x, y);
        p = 1;
        x[sa[0]] = 0;
        for (int i = 1; i < n; ++i) {
            x[sa[i]] = (y[sa[i - 1]] == y[sa[i]] && sa[i - 1] + len < n && y[sa[i - 1] + len] == y[sa[i] + len]) ? p - 1 : p++;
        }
    }
    for (int i = 0; i < n; ++i) rk[sa[i]] = i;
    for (int i = 0, k = 0; i < n; ++i) {
        if (rk[i] == 0) continue;
        if (k) k--;
        int j = sa[rk[i] - 1];
        while (s[i + k] == s[j + k]) k++;
        h[rk[i]] = k;
    }
}

void build_st() {
    for (int i = 0; i < n; ++i) st[i][0] = h[i];
    for (int j = 1; (1 << j) <= n; ++j) {
        for (int i = 0; i + (1 << j) <= n; ++i) {
            st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int get_min(int l, int r) {
    int j = 31 - __builtin_clz(r - l + 1);
    return min(st[l][j], st[r - (1 << j) + 1][j]);
}
pair<int, int> find(int k) {
    for (int i = 0; i < n; ++i) {
        int len = n - sa[i];
        if (k <= len) return {sa[i] + 1, sa[i] + k};
        k -= len;
        if (i + 1 < n) {
            int lcp = get_min(i + 1, rk[sa[i]]);
            if (k <= lcp * (lcp + 1) / 2) {
                int l = 1, r = lcp, res = 0;
                while (l <= r) {
                    int mid = (l + r) >> 1;
                    if (mid * (mid + 1) / 2 >= k) res = mid, r = mid - 1;
                    else l = mid + 1;
                }
                return {sa[i] + 1, sa[i] + res};
            }
            k -= lcp * (lcp + 1) / 2;
        }
    }
    return {0, 0};
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> q;
    for (int i = 0; i < n; ++i) cin >> a[i], s[i] = a[i];
    build_sa();
    build_st();
    while (q--) {
        int k;
        cin >> k;
        auto [l, r] = find(k);
        cout << l << ' ' << r << '\n';
    }
    return 0;
}
2024/8/25 19:00
加载中...