zoukankan      html  css  js  c++  java
  • [P6139] 【模板】广义后缀自动机

    Description

    给定 (n) 个由小写字母组成的字符串 (s_1,s_2ldots 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;
    }
    
    
    
    
  • 相关阅读:
    文件光标移动
    python的版本的差别 "2","3"
    java通过jdbc操作Excel
    qt通过odbc操作Excel
    qt读取oracle表数据
    virtual box安装oracle_rac_10g
    oracle rac +standby
    rac不完全恢复
    rac完全恢复学习
    oracle rac搭建(三)--安装中的问题
  • 原文地址:https://www.cnblogs.com/mollnn/p/13289162.html
Copyright © 2011-2022 走看看