zoukankan      html  css  js  c++  java
  • 【SPOJ

    题意

      求出多个串的最长公共子串。

    分析

       刚学SAM想做这个题的话最好先去做一下那道codevs3160。求两个串的LCS应该怎么求?把一个串s1建自动机,然后跑另一个串s2,然后找出s2每个前缀的最长公共后缀。那么多个的时候,我们也用这种类似的方法,但是我们求最长公共后缀的时候要求第一个串的。我们把其中一个串建SAM,然后把其他的串都在上面跑,维护两个值,Max[u]和Min[u]。自动机中每个状态u的Right存的是结尾集合。那么对于一个字符串,我们可以求出他和自动机中每个状态的最长公共后缀。然后,我们通过Max[fa[u]]=max(Max[fa[u]],Max[u])来确定左右状态的最长公共后缀,然后更新Min[o]。

    下面的代码没有AC,但是我找了好久BUG没找到··如果有人看完并且找到了bug麻烦跟我说一下万分感谢!

      

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 const int maxn=300000+100;
     8 char s[maxn];
     9 struct state{
    10     int len,link;
    11     int next[26];
    12 }st[2*maxn];
    13 int n,last,cur,sz;
    14 int Min[2*maxn],Max[2*maxn],c[2*maxn];
    15 
    16 void init(){
    17     sz=1;
    18     cur=last=0;
    19     st[0].link=-1;
    20     st[0].len=0;
    21 }
    22 
    23 void build_sam(int c){
    24     cur=sz++;
    25     st[cur].len=st[last].len+1;
    26     Min[cur]=st[cur].len;
    27     int p;
    28     for(p=last;p!=-1&&st[p].next[c]==0;p=st[p].link)
    29         st[p].next[c]=cur;
    30     if(p==-1)
    31         st[cur].link=0;
    32     else{
    33         int q=st[p].next[c];
    34         if(st[q].len==st[p].len+1)
    35             st[cur].link=q;
    36         else{
    37             int clone=sz++;
    38             st[clone].len=st[p].len+1;
    39             Min[clone]=st[clone].len;
    40             st[clone].link=st[q].link;
    41             for(int i=0;i<26;i++)
    42                 st[clone].next[i]=st[q].next[i];
    43             for(;p!=-1&&st[p].next[c]==q;p=st[p].link)
    44                 st[p].next[c]=clone;
    45             st[cur].link=st[q].link=clone;
    46         }
    47     }
    48     last=cur;
    49 }
    50 
    51 int cmp(int a,int b){
    52     return st[a].len<st[b].len;
    53 }
    54 
    55 int main(){
    56     scanf("%s",s);
    57     n=strlen(s);
    58     init();
    59 
    60     for(int i=0;i<n;i++)
    61         build_sam(s[i]-'a');
    62     for(int i=0;i<sz;i++)
    63         c[i]=i;
    64     sort(c,c+sz,cmp);
    65 
    66     while(scanf("%s",s)!=EOF){
    67         n=strlen(s);
    68         int u=0,len=0;
    69         for(int i=0;i<n;i++){
    70             int c=s[i]-'a';
    71             if(u!=-1&&st[u].next[c]==0)
    72                 u=st[u].link,len=st[u].len;
    73             if(u==-1)
    74                 u=0,len=0;
    75             else{
    76                 u=st[u].next[c];
    77                 len++;
    78                 Max[u]=max(Max[u],len);
    79             }
    80         }
    81 
    82         for(int i=sz-1;i>=0;i--){
    83             int o=c[i];
    84             Min[o]=min(Min[o],Max[o]);
    85             if(st[o].link!=-1){
    86                 Max[st[o].link]=max(Max[st[o].link],Max[o]);
    87             }
    88             Max[o]=0;
    89         }
    90     }
    91     int ans=0;
    92     for(int i=0;i<sz;i++){
    93         ans=max(ans,Min[i]);
    94     }
    95     printf("%d
    ",ans);
    96 
    97 return 0;
    98 }
    View Code
  • 相关阅读:
    JSON中toJSONString、ParseObject、parseArray的作用以及用 com.alibaba.fast.JSONArray解析字符串或者List集合
    几种操作Elasticsearch方法
    ElasticSearch 中boolQueryBuilder的使用
    maven依赖
    @javax.ws.rs Webservice注解
    Bug-滑稽
    Web安全之文件上传
    利用SSRF漏洞内网探测来攻击Redis(通过curl命令 & gopher协议)
    利用SSRF漏洞内网探测来攻击Redis(请求头CRLF方式)
    SVG XSS一般过程
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9885912.html
Copyright © 2011-2022 走看看