题目分析:
用没出现过的字符搞拼接。搞出right树,找right集合的最小和最大。如果最小和最大分居两侧可以更新答案。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 1000500; 5 6 int son[maxn][30],fa[maxn],maxlen[maxn],root,num,sigma = 27; 7 int minn[maxn],maxx[maxn];// lright rright 8 9 string str,ss; 10 int n,m; 11 vector<int> T[maxn]; 12 13 int addnew(int dt){maxlen[++num] = dt;return num;} 14 int ins(char x,int p,int hhhh){ 15 int np = addnew(maxlen[p]+1); minn[np] = maxx[np] = hhhh; 16 while(p && !son[p][x-'a']) son[p][x-'a'] = np,p = fa[p]; 17 if(!p){fa[np] = root; return np;} 18 else{ 19 int q = son[p][x-'a']; 20 if(maxlen[q]==maxlen[p]+1){fa[np]=q;return np;} 21 else{ 22 int nq = addnew(maxlen[p]+1); 23 for(int i=0;i<sigma;i++) son[nq][i] = son[q][i]; 24 fa[nq] = fa[q]; fa[q] = fa[np] = nq; 25 while(p && son[p][x-'a'] == q) son[p][x-'a'] = nq,p = fa[p]; 26 return np; 27 } 28 } 29 } 30 31 void dfs(int now){ 32 if(!minn[now]) minn[now] = 1e9; 33 for(int i=0;i<T[now].size();i++){ 34 dfs(T[now][i]); 35 minn[now] = min(minn[now],minn[T[now][i]]); 36 maxx[now] = max(maxx[now],maxx[T[now][i]]); 37 } 38 } 39 40 void work(){ 41 int lst = addnew(0);root = lst; 42 for(int i=0;i<str.length();i++) 43 lst = ins(str[i],lst,i+1); 44 for(int i=2;i<=num;i++) T[fa[i]].push_back(i); 45 dfs(1); int ans = 0; 46 for(int i=1;i<=num;i++)if(minn[i]<=n&&maxx[i]>n+1)ans=max(ans,maxlen[i]); 47 cout<<ans<<endl; 48 } 49 50 int main(){ 51 ios::sync_with_stdio(false); 52 cin.tie(0); 53 cin >> str; cin >> ss; 54 n = str.length(); m = ss.length(); 55 str += ('z'+1); str += ss; 56 work(); 57 return 0; 58 }