zoukankan      html  css  js  c++  java
  • 多个串的最长公共子串 SPOJ

    题意:

    求多个串的最长公共子串

    这里用的是O(n)的后缀自动机写法

    我后缀数组的专题有nlog(n)写法的

    题解:

    对于其中的一个串建立后缀自动机

    然后对于后缀自动机上面的每一个节点求出每一个节点最长可以匹配的子串(用maxx【】数组存下)

    但是在后缀自动机上面有些节点没有走过,但是是某些走过的点的父亲节点因此也是有值的

    for (int i = tot; i; i--)
    maxx[fail[i]] = max(maxx[fail[i]], min(len[fail[i]], maxx[i]));

    然后求一个所有最小值里面的最大值就好了

      1 #include <set>
      2 #include <map>
      3 #include <stack>
      4 #include <queue>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <cstdio>
      8 #include <string>
      9 #include <vector>
     10 #include <cstring>
     11 #include <iostream>
     12 #include <algorithm>
     13 #include <unordered_map>
     14 
     15 #define  pi    acos(-1.0)
     16 #define  eps   1e-9
     17 #define  fi    first
     18 #define  se    second
     19 #define  rtl   rt<<1
     20 #define  rtr   rt<<1|1
     21 #define  bug                printf("******
    ")
     22 #define  mem(a, b)          memset(a,b,sizeof(a))
     23 #define  name2str(x)        #x
     24 #define  fuck(x)            cout<<#x" = "<<x<<endl
     25 #define  sfi(a)             scanf("%d", &a)
     26 #define  sffi(a, b)         scanf("%d %d", &a, &b)
     27 #define  sfffi(a, b, c)     scanf("%d %d %d", &a, &b, &c)
     28 #define  sffffi(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
     29 #define  sfL(a)             scanf("%lld", &a)
     30 #define  sffL(a, b)         scanf("%lld %lld", &a, &b)
     31 #define  sfffL(a, b, c)     scanf("%lld %lld %lld", &a, &b, &c)
     32 #define  sffffL(a, b, c, d) scanf("%lld %lld %lld %lld", &a, &b, &c, &d)
     33 #define  sfs(a)             scanf("%s", a)
     34 #define  sffs(a, b)         scanf("%s %s", a, b)
     35 #define  sfffs(a, b, c)     scanf("%s %s %s", a, b, c)
     36 #define  sffffs(a, b, c, d) scanf("%s %s %s %s", a, b,c, d)
     37 #define  FIN                freopen("../in.txt","r",stdin)
     38 #define  gcd(a, b)          __gcd(a,b)
     39 #define  lowbit(x)          x&-x
     40 #define  IO                 iOS::sync_with_stdio(false)
     41 
     42 
     43 using namespace std;
     44 typedef long long LL;
     45 typedef unsigned long long ULL;
     46 const ULL seed = 13331;
     47 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
     48 const int maxn = 1e6 + 50;
     49 const int maxm = 8e6 + 10;
     50 const int INF = 0x3f3f3f3f;
     51 const int mod = 1e9 + 7;
     52 char s[maxn];
     53 
     54 struct Suffix_Automaton {
     55     int last, tot, nxt[maxn << 1][26], fail[maxn << 1];//last是未加入此字符前最长的前缀(整个串)所属的节点的编号
     56     int len[maxn << 1];// 最长子串的长度 (该节点子串数量 = len[x] - len[fail[x]])
     57     int maxx[maxn << 1];
     58 
     59     void init() {
     60         tot = last = 1;
     61         fail[1] = len[1] = 0;
     62         for (int i = 0; i < 26; i++) nxt[1][i] = 0;
     63     }
     64 
     65     void extend(int c) {
     66         int u = ++tot, v = last;
     67         for (int i = 0; i < 26; i++) nxt[u][i] = 0;
     68         fail[u] = 0;
     69         len[u] = len[v] + 1;
     70         for (; v && !nxt[v][c]; v = fail[v]) nxt[v][c] = u;
     71         if (!v) fail[u] = 1;
     72         else if (len[nxt[v][c]] == len[v] + 1) fail[u] = nxt[v][c];
     73         else {
     74             int now = ++tot, cur = nxt[v][c];
     75             len[now] = len[v] + 1;
     76             memcpy(nxt[now], nxt[cur], sizeof(nxt[cur]));
     77             fail[now] = fail[cur];
     78             fail[cur] = fail[u] = now;
     79             for (; v && nxt[v][c] == cur; v = fail[v]) nxt[v][c] = now;
     80         }
     81         last = u;
     82         //return len[last] - len[fail[last]];//添加一个新的字符产生的新的本质不同的子串数目
     83     }
     84 
     85     int minn[maxn << 1];
     86 
     87     void match() {
     88         mem(maxx, 0);
     89         int n = strlen(s);
     90         int p = 1, maxlen = 0;
     91         for (int i = 0; i < n; i++) {
     92             int c = s[i] - 'a';
     93             if (nxt[p][c]) p = nxt[p][c], maxlen++;
     94             else {
     95                 for (; p && !nxt[p][c]; p = fail[p]);
     96                 if (!p) p = 1, maxlen = 0;
     97                 else maxlen = len[p] + 1, p = nxt[p][c];
     98             }
     99             maxx[p] = max(maxx[p], maxlen);
    100         }
    101         for (int i = tot; i; i--)
    102             maxx[fail[i]] = max(maxx[fail[i]], min(len[fail[i]], maxx[i]));
    103         for (int i = tot; i; i--)
    104             if (minn[i] == -1 || minn[i] > maxx[i]) minn[i] = maxx[i];
    105     }
    106 
    107 } sam;
    108 
    109 
    110 int main() {
    111 #ifndef ONLINE_JUDGE
    112     FIN;
    113 #endif
    114     sfs(s);
    115     int n = strlen(s);
    116     sam.init();
    117     for (int i = 0; i < n; ++i) sam.extend((s[i] - 'a'));
    118     for (int i = 0; i <= sam.tot; i++) sam.minn[i] = -1;
    119     while (~sfs(s)) sam.match();
    120     int ans = 0;
    121     for (int i = 1; i <= sam.tot; i++) ans = max(ans, sam.minn[i]);
    122     printf("%d
    ", ans);
    123 #ifndef ONLINE_JUDGE
    124     cout << "Totle Time : " << (double) clock() / CLOCKS_PER_SEC << "s" << endl;
    125 #endif
    126     return 0;
    127 }
    View Code



  • 相关阅读:
    简介.Net对象序列化.txt
    如何在Web页面退出前提示用户保存数据?
    如何将图片存储到数据库中
    页面回车键响应,onkeydown事件
    用C#创建Windows服务(Windows Services)
    解决“Visual Studio 要求设计器使用文件中的第一个类。移动类代码使之成为文件中的第一个类,然后尝试重新加载设计器。”方法
    动态创建htm元素并添加到document中
    如何在Asp.net的Header中添加/title/Meta tages/CSS
    无法打开项目文件,“d:\web\webapp.csproj”,此安装不支持该项目类型
    用Intelligencia.UrlRewriter实现URL重写
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/11545062.html
Copyright © 2011-2022 走看看