AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 应用
  • 其它
    • 题解
    • 分享
    • 商店
    • 问答
  • 吐槽
  • 登录/注册

AcWing 841. 正经后缀数组做法    原题链接    简单

作者: 作者的头像   Yangchang ,  2023-01-25 22:18:12 ,  所有人可见 ,  阅读 28


1


#include<bits/stdc++.h>
#define cint const int&
#define cstr const auto*const
using namespace std;
const int maxn = 1e5 + 1, lim = 30;
int l1, l2, r1, r2, a[maxn], sa[maxn], rk[maxn], tp[maxn << 1], bn[maxn], hzr[maxn], n, m;
char s[maxn];
inline void getsa(cstr s, cint n) {
    int m = max(n, 255);
    memset(bn + 1, 0, sizeof(bn[0]) * m);
    for (int i = 1; i <= n; ++i) ++bn[rk[i] = s[i]];
    for (int i = 2; i <= m; ++i) bn[i] += bn[i - 1];
    for (int i = n; i > 0; --i) sa[bn[rk[i]]--] = i;
    for (int j = 1, cnt = 0; j <= n; j <<= 1, cnt = 0) {
        for (int i = n - j + 1; i <= n; ++i) tp[++cnt] = i;
        for (int i = 1; i <= n; ++i)
            if (sa[i] - j > 0) tp[++cnt] = sa[i] - j;
        memset(bn + 1, 0, sizeof(bn[0]) * m);
        for (int i = 1; i <= n; ++i) ++bn[rk[i]];
        for (int i = 2; i <= m; ++i) bn[i] += bn[i - 1];
        for (int i = n; i > 0; --i) sa[bn[rk[tp[i]]]--] = tp[i];
        memcpy(tp + 1, rk + 1, sizeof(tp[0]) * n);
        rk[sa[1]] = cnt = 1;
        for (int i = 2; i <= n; ++i)
            rk[sa[i]] = (tp[sa[i]] != tp[sa[i - 1]]) || (tp[sa[i] + j] != tp[sa[i - 1] + j]) ? ++cnt : cnt;
        if ((m = cnt) == n) break;
    }
}
inline void gethzr(cstr s, cint n) {
    for (int i = 1, k = 0; i <= n; ++i) {
        if (rk[i] == 1) continue;
        if (k) --k;
        int j = sa[rk[i] - 1];
        while (j + k <= n && i + k <= n && s[i + k] == s[j + k]) ++k;
        hzr[rk[i]] = k;
    }
}

int minval[lim][maxn];
inline void init(cint n) {
    for (int i = 1; i < lim; ++i)
        for (int j = 1; j + (1 << (i - 1)) <= n; ++j)
        minval[i][j] = min(minval[i - 1][j], minval[i - 1][j + (1 << (i - 1))]);
}
inline int getmin(cint l, cint r) {
    int lg = (8 * sizeof(r - l + 1) - 1) - __builtin_clz(r - l + 1);
    return min(minval[lg][l], minval[lg][r - (1 << lg) + 1]);
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m >> s + 1;
    getsa(s, n), gethzr(s, n);
    memcpy(minval[0], hzr, sizeof(hzr[0]) * (n + 1)), init(n);
    while (m--) {
        cin >> l1 >> r1 >> l2 >> r2;
        if (rk[l1] > rk[l2]) swap(l1, l2), swap(r1, r2);
        if (r1 - l1 == r2 - l2 && (l1 == l2 || getmin(rk[l1] + 1, rk[l2]) > r1 - l1))
            cout << "Yes\n";
        else cout << "No\n";
    }
}

0 评论

你确定删除吗?
1024
x

© 2018-2023 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息