• SPOJ1811 后缀自动机入门


    题目链接点我点我:-)

    题目描述
    求两个字符串的最长公共子串的长度,字符串长度小于等于5105

    输入格式
    两行即两个字符串

    输出格式
    一个整数,表示两个字符串的最长公共子串的长度

    思路
    后缀自动机裸题,入门的一个好的讲解:传送门

    感想
    还是有一些地方不是很理解,特别是匹配的时候有点乱(关于step的问题)
    还有一个同学的习题锦集,可以去做一下:传送门
    (ps: 下方程序中的Query函数并没有用)

    代码

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    #define For(i, a, b) for(int i = (a); i <= (int)(b); ++i)
    #define N (500000+5)
    
    struct Suffix_Automaton{
        char s[N];
        int son[N][26], pre[N], step[N], root, last, Tot;
    
        void Insert(char ch){
            ch -= 'a';
    
            int p = last, np = ++Tot;
            step[np] = step[last]+1; last = np;
    
            for(;p&&!son[p][ch]; p=pre[p]) son[p][ch] = np;
            if(!p) pre[np] = root;
            else{
                if(step[p]+1 == step[son[p][ch]]) pre[np] = son[p][ch];
                else{
                    int q = son[p][ch], nq = ++Tot;
    
                    pre[nq] = pre[q]; step[nq] = step[p]+1;
                    For(i, 0, 25) son[nq][i] = son[q][i];
                    pre[q] = pre[np] = nq;
                    for(;son[p][ch]==q; p=pre[p]) son[p][ch] = nq;
                }
            }
        }
    
        int Query(char *s){
            int nc, now = root, len = strlen(s);
            For(i, 0, len-1){
                nc = s[i]-'a';
                if(!son[now][nc]) return i;
                now = son[now][nc];
            }
            return len;
        }
    }sat;
    
    char s1[N], s2[N];
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("test.in", "r", stdin);
        freopen("test.out", "w", stdout);
    #endif
    
        sat.root = sat.last = ++sat.Tot;
        scanf("%s%s", s1, s2);
    
        int len1 = strlen(s1), len2 = strlen(s2);
        For(i, 0, len1-1) sat.Insert(s1[i]);
    
        int ans = 0, len = 0, now = sat.root;
        char ch;
        For(i, 0, len2-1){
            ch = s2[i]-'a';
    
            if(sat.son[now][ch]) ++len, now = sat.son[now][ch];
            else{
                while(now && !sat.son[now][ch]) now = sat.pre[now];
                if(!now) now = sat.root, len = 0;
                else len = sat.step[now]+1, now = sat.son[now][ch]; 
            }
            ans = max(ans, len);
        }
        printf("%d
    ", ans);
    
        return 0;
    }
  • 相关阅读:
    Angularjs演示Service功能
    初始化应用程序数据ng-init指令
    AngularJs的ng-include的使用与实现
    把视图转换为字符串
    学习angularjs的内置API函数
    AngularJs自定义过滤器filter
    ASP.NET MVC的切片(Section)脚本(script)
    在ASP.NET MVC部署AngularJs
    MS SQL的某一数据库成了Single User模式
    AngularJs的MVC模式
  • 原文地址:https://www.cnblogs.com/miaomiao1220/p/6642333.html
Copyright © 2020-2023  润新知