首页 > 其他 > 详细

Luogu P4070 [SDOI2016]生成魔咒

时间:2019-03-03 23:32:01      阅读:148      评论:0      收藏:0      [点我收藏+]

题目链接 \(Click\) \(Here\)

其实是看后缀数组资料看到这个题目的,但是一眼反应显然后缀自动机,每次维护添加节点后的答案贡献即可,唯一不友好的一点是需要平衡树维护,这里因为复杂度不卡而且也不需要用到\(ch\)数组的遍历访问,我采用了\(map\)的写法。

其实是因为不会平衡树维护啦,如果有机会还是要学一下啊。。这个题可是没给不用平衡树的部分分啊\(Qwq\)(直接全体\(1e9\)

#include <bits/stdc++.h>
using namespace std;

const int N = 200010;

struct Suffix_Auto {
    int cnt, las; long long ans;
    int fa[N], len[N];
    map <int, int> ch[N];

    Suffix_Auto () {
        cnt = las = 1; ans = 0;
        memset (fa, 0, sizeof (fa));
        memset (len, 0, sizeof (len));
    }
    
    void extend (int c) {
        int p = las, q = ++cnt; las = q;
        len[q] = len[p] + 1;
        while (p != 0 && ch[p][c] == 0) {
            ch[p][c] = q;
            p = fa[p];
        }
        ans += len[q];
        if (p == 0) {
            fa[q] = 1;
        } else {
            int x = ch[p][c];
            if (len[x] == len[p] + 1) {
                fa[q] = x;
                ans -= len[x];
            } else {
                int y = ++cnt;
                fa[y] = fa[x];
                fa[x] = fa[q] = y;
                len[y] = len[p] + 1;
                ch[y] = ch[x];
                while (p != 0 && ch[p][c] == x) {
                    ch[p][c] = y;
                    p = fa[p];
                }
                ans -= len[y];
            }
        }
        cout << ans << endl;
    }
}sam;

int n, num;

int main () {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sam.extend (num);
    }
}

Luogu P4070 [SDOI2016]生成魔咒

原文:https://www.cnblogs.com/maomao9173/p/10468425.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!