• SPOJ-LCS Longest Common Substring 【后缀自动机】


    题目分析:

    用没出现过的字符搞拼接。搞出right树,找right集合的最小和最大。如果最小和最大分居两侧可以更新答案。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 1000500;
     5 
     6 int son[maxn][30],fa[maxn],maxlen[maxn],root,num,sigma = 27;
     7 int minn[maxn],maxx[maxn];// lright rright
     8 
     9 string str,ss;
    10 int n,m;
    11 vector<int> T[maxn];
    12 
    13 int addnew(int dt){maxlen[++num] = dt;return num;}
    14 int ins(char x,int p,int hhhh){
    15     int np = addnew(maxlen[p]+1); minn[np] = maxx[np] = hhhh;
    16     while(p && !son[p][x-'a']) son[p][x-'a'] = np,p = fa[p];
    17     if(!p){fa[np] = root; return np;}
    18     else{
    19     int q = son[p][x-'a'];
    20     if(maxlen[q]==maxlen[p]+1){fa[np]=q;return np;}
    21     else{
    22         int nq = addnew(maxlen[p]+1);
    23         for(int i=0;i<sigma;i++) son[nq][i] = son[q][i];
    24         fa[nq] = fa[q]; fa[q] = fa[np] = nq;
    25         while(p && son[p][x-'a'] == q) son[p][x-'a'] = nq,p = fa[p];
    26         return np;
    27     }
    28     }
    29 }
    30 
    31 void dfs(int now){
    32     if(!minn[now]) minn[now] = 1e9;
    33     for(int i=0;i<T[now].size();i++){
    34     dfs(T[now][i]);
    35     minn[now] = min(minn[now],minn[T[now][i]]);
    36     maxx[now] = max(maxx[now],maxx[T[now][i]]);
    37     }
    38 }
    39 
    40 void work(){
    41     int lst = addnew(0);root = lst;
    42     for(int i=0;i<str.length();i++)
    43     lst = ins(str[i],lst,i+1);
    44     for(int i=2;i<=num;i++) T[fa[i]].push_back(i);
    45     dfs(1); int ans = 0;
    46     for(int i=1;i<=num;i++)if(minn[i]<=n&&maxx[i]>n+1)ans=max(ans,maxlen[i]);
    47     cout<<ans<<endl;
    48 }
    49 
    50 int main(){
    51     ios::sync_with_stdio(false);
    52     cin.tie(0);
    53     cin >> str; cin >> ss;
    54     n = str.length(); m = ss.length();
    55     str += ('z'+1); str += ss;
    56     work();
    57     return 0;
    58 }
  • 相关阅读:
    与(&,&&)和或(|,||)的区别
    vue笔记(更新中)
    echarts实现心脏图的滚动三种实现方法
    生成四则运算
    软件工程第四次作业
    软件工程第三次作业
    软件工程第二次作业
    软件工程第一次作业
    前端优化
    关于事件监听
  • 原文地址:https://www.cnblogs.com/Menhera/p/10306444.html
Copyright © 2020-2023  润新知