zoukankan      html  css  js  c++  java
  • SPOJ1811 最长公共子串

    如题

    N<=250000

    倍增后缀数组和DC3都过不了  ,据说有的人DC3能过

    后缀自动机

    首先对A串建立后缀自动机

    然后让B在A上匹配

    考虑B的逐位匹配,维护一个cur节点,一开始这个节点是空节点,也就是1

    然后如果cur的转移里面有B[i] ,那么ans++,  cur转移到下个节点

    如果匹配不到,那么往他的fa去走,判断是否有转移,如果有转移就更新一下

    然后维护最大答案就可以了

    #include<bits/stdc++.h>
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,a,n) for(int i=n;i>=a;--i)
    #define pb push_back
    #define fi first
    #define se second
    #define io std::ios::sync_with_stdio(false)
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int P = 1e9+7, INF = 0x3f3f3f3f;
    
    ll gcd(ll a,ll b)
    {
        return b?gcd(b,a%b):a;
    }
    ll qpow(ll a,ll n)
    {
        ll r=1%P;
        for (a%=P; n; a=a*a%P,n>>=1)if(n&1)r=r*a%P;
        return r;
    }
    const int maxn=2e6;
    
    struct Suffix_Automata {
      int maxlen[maxn], trans[maxn][26], link[maxn], Size, Last;
      int siz[maxn];
      int t[maxn],A[maxn];
      Suffix_Automata() { Size = Last = 1; }
      inline void Extend(int id) {
        int cur = (++ Size), p;
        siz[Size]=1;
        maxlen[cur] = maxlen[Last] + 1;
        for (p = Last; p && !trans[p][id]; p = link[p]) trans[p][id] = cur;
        if (!p) link[cur] = 1;
        else {
          int q = trans[p][id];
          if (maxlen[q] == maxlen[p] + 1) link[cur] = q;
          else {
            int clone = (++ Size);
            maxlen[clone] = maxlen[p] + 1;
            memcpy(trans[clone], trans[q],sizeof(trans[q]));
            link[clone] = link[q];
            for (; p && trans[p][id] == q; p = link[p]) trans[p][id] = clone;
            link[cur] = link[q] = clone;
          }
        }
        Last = cur;
      }
      void buildtree()
      {
          for(int i=1;i<=Size;i++) t[maxlen[i]]++;
          for(int i=1;i<=Size;i++) t[i]+=t[i-1];
          for(int i=1;i<=Size;i++) A[t[maxlen[i]]--]=i;
      }
    } T;
    char s[250005];
    char a[250005];
    int main()
    {
         cin>>s+1;
         int n=strlen(s+1);
         for(int i=1;i<=n;i++)
         {
           T.Extend(s[i]-'a');
         }
         cin>>a+1;
         int ans=0;
         int len=strlen(a+1);
         int cur=1;
         int _max=0;
         for(int i=1;i<=len;i++)
         {   int now=a[i]-'a';
             if(T.trans[cur][now])
             {
                ans++;
                cur=T.trans[cur][now];
             }
             else
             {
                 while(!T.trans[cur][now]&&cur!=1)
                    cur=T.link[cur];
                 if(T.trans[cur][now])
                 {
    
                     ans=T.maxlen[cur]+1;
                     cur=T.trans[cur][now];
                 }
                 else
                    ans=0;
             }
             _max=max(_max,ans);
         }
         cout<<_max<<endl;
    }
  • 相关阅读:
    React元素渲染
    初识JSX
    微信小程序复制文本到剪切板
    微信小程序报错request:fail url not in domain list
    小程序,通过自定义编译条件,模拟推荐人功能
    积分抵扣逻辑
    微信小程序 switch 样式
    tomcat 配置开启 APR 模式
    tomcat8 传输json 报错 Invalid character found in the request target. The valid characters are defined in RFC 3986
    c++数组初始化误区
  • 原文地址:https://www.cnblogs.com/acmLLF/p/13646451.html
Copyright © 2011-2022 走看看