• [SPOJ-LCS]Longest Common Substring


    题目大意:
      求两个字符串的LCS。

    思路:
      对其中一个字符串构建SAM,然后用另一个字符串在里面匹配,按照SAM的边一直往下走,匹配到的连续的字符数就是公共字串的长度。

     1 #include<string>
     2 #include<cstring>
     3 #include<iostream>
     4 std::string s,t;
     5 class SuffixAutomaton {
     6     private:
     7         static const int SIGMA_SIZE=26;
     8         int idx(const char ch) {
     9             return ch-'a';
    10         }
    11         struct State {
    12             State *link,*go[SIGMA_SIZE];
    13             int len;
    14             State(const int l) {
    15                 link=NULL;
    16                 len=l;
    17                 memset(go,0,sizeof go);
    18             }
    19         };
    20         State *root,*last;
    21         void extend(const char ch) {
    22             int w=idx(ch);
    23             State *p=last;
    24             State *new_p=new State(p->len+1);
    25             while(p!=NULL&&p->go[w]==NULL) {
    26                 p->go[w]=new_p;
    27                 p=p->link;
    28             }
    29             if(p==NULL) {
    30                 new_p->link=root;
    31             } else {
    32                 State *q=p->go[w];
    33                 if(q->len==p->len+1) {
    34                     new_p->link=q;
    35                 } else {
    36                     State *new_q=new State(p->len+1);
    37                     memcpy(new_q->go,q->go,sizeof q->go);
    38                     new_q->link=q->link;
    39                     q->link=new_p->link=new_q;
    40                     while(p!=NULL&&p->go[w]==q) {
    41                         p->go[w]=new_q;
    42                         p=p->link;
    43                     }
    44                 }
    45             }
    46             last=new_p;
    47         }
    48     public:
    49         void build(std::string &s) {
    50             last=root=new State(0);
    51             for(std::string::iterator i=s.begin();i<s.end();i++) extend(*i);
    52         }
    53         int match(std::string &s) {
    54             int ret=0,tmp=0;
    55             State *p=root;
    56             for(std::string::iterator i=s.begin();i<s.end();i++) {
    57                 int w=idx(*i);
    58                 if(p!=NULL&&p->go[w]!=NULL) {
    59                     p=p->go[w];
    60                     tmp++;
    61                 } else {
    62                     while(p!=NULL&&p->go[w]==NULL) p=p->link;
    63                     if(p==NULL) {
    64                         p=root;
    65                         tmp=0;
    66                     } else {
    67                         tmp=p->len+1;
    68                         p=p->go[w];
    69                     }
    70                 }
    71                 ret=std::max(ret,tmp);
    72             }
    73             return ret;
    74         }
    75 };
    76 SuffixAutomaton sam;
    77 int main() {
    78     std::ios_base::sync_with_stdio(false);
    79     std::cin.tie(NULL);
    80     std::cin>>s;
    81     sam.build(s);
    82     std::cin>>s;
    83     std::cout<<sam.match(s)<<std::endl;
    84     return 0;
    85 }
  • 相关阅读:
    python编码
    异常、调试
    python的优点
    循环、判断
    对象
    模块
    函数
    变量
    Socket编程(九)
    进程简单了解和使用
  • 原文地址:https://www.cnblogs.com/skylee03/p/7509558.html
Copyright © 2020-2023  润新知