码迷,mamicode.com
首页 > 其他好文 > 详细

[P6139] 【模板】广义后缀自动机 - 广义SAM

时间:2020-07-12 18:26:50      阅读:49      评论:0      收藏:0      [点我收藏+]

标签:不同的   sig   inline   with   sam   int   efi   solution   str   

Description

给定 \(n\) 个由小写字母组成的字符串 \(s_1,s_2\ldots s_n\),求本质不同的子串个数。(不包含空串)

Solution

每个串插入完后将 SAM 指回 \(root\),这样建立广义 SAM 还是不够的,需要一些奇怪的特判(见代码中 //! 部分)

(具体分析先鸽了)

答案就是 \(\sum (maxlen[i]-minlen[i]+1)\)

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2000005;
struct SAM {
    int len[N], ch[N][26], fa[N], ind, last;
    SAM() { ind = last = 1; }
    inline int extend(int id) {
        if(ch[last][id] && len[last]+1==len[ch[last][id]]) return ch[last][id]; //!
        int cur = (++ ind), p, tmp, flag = 0; //!
        len[cur] = len[last] + 1;
        for (p = last; p && !ch[p][id]; p = fa[p]) ch[p][id] = cur;
        if (!p) fa[cur] = 1;
        else {
            int q = ch[p][id];
            if (len[q] == len[p] + 1) fa[cur] = q;
            else {
                if(p==last) flag=1; //!
                tmp = (++ ind);
                len[tmp] = len[p] + 1;
                for(int i=0;i<26;i++) ch[tmp][i] = ch[q][i];
                fa[tmp] = fa[q];
                for (; p && ch[p][id] == q; p = fa[p]) ch[p][id] = tmp;
                fa[cur] = fa[q] = tmp;
            }
        }
        last = cur;
        return flag ? tmp : cur;//!
    }
    void extend(string s)
    {
        for(int i=0;i<s.length();i++)
        {
            last = extend(s[i]-‘a‘);
        }
        last = 1;
    }
    int solve()
    {
        int ans=0;
        for(int i=1;i<=ind;i++)
        {
            ans+=len[i]-len[fa[i]];
        }
        return ans;
    }
} sam;

signed main() {
    ios::sync_with_stdio(false);
    int n;
    string str;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>str;
        sam.extend(str);
    }
    cout<<sam.solve()<<endl;
}



[P6139] 【模板】广义后缀自动机 - 广义SAM

标签:不同的   sig   inline   with   sam   int   efi   solution   str   

原文地址:https://www.cnblogs.com/mollnn/p/13289162.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!