• 【洛谷 P2408】 不同子串个数(后缀自动机)


    题目链接
    裸体就是身体。
    建出(SAM)(DAG)上跑(DP)(f[u]=1+sum_{(u,v)in DAG}f[v])
    答案为(f[1]-1)(因为根节点没有字符)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAXN = 1000010;
    struct SAM{
        int ch[26];
        int len, fa;
    }sam[MAXN << 1];
    int las = 1, cnt = 1;
    long long f[MAXN << 1];
    inline void add(int c){
        int p = las; int np = las = ++cnt;
        sam[np].len = sam[p].len + 1;
        for(; p && !sam[p].ch[c]; p = sam[p].fa) sam[p].ch[c] = np;
        if(!p) sam[np].fa = 1;
        else{
            int q = sam[p].ch[c];
            if(sam[q].len == sam[p].len + 1) sam[np].fa = q;
            else{
                int nq = ++cnt; sam[nq] = sam[q];
                sam[nq].len = sam[p].len + 1;
                sam[q].fa = sam[np].fa = nq;
                for(; p && sam[p].ch[c] == q; p = sam[p].fa) sam[p].ch[c] = nq;
            }
        }
    }
    char a[MAXN];
    long long ans;
    void dfs(int u){
        f[u] = 1;
        for(int i = 0; i < 26; ++i)
            if(sam[u].ch[i]){
                if(!f[sam[u].ch[i]])
                    dfs(sam[u].ch[i]);
                f[u] += f[sam[u].ch[i]];
            }
    }
    int len;
    int main(){
        scanf("%d", &len);
        scanf("%s", a + 1);
        for(int i = 1; i <= len; ++i)
           add(a[i] - 'a');
        dfs(1);
        printf("%lld
    ", f[1] - 1);
        return 0;
    }
    
    
  • 相关阅读:
    Elasticsearch的RESTful API使用
    Elasticsearch简介与安装
    安装MySQL
    数据处理与文件查找,压缩与解压
    Linux网络设置
    文件与文件夹
    基本命令
    se
    爬虫请求库之requests
    redis五种数据类型
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/10986643.html
Copyright © 2020-2023  润新知