如题
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; }