Longest Common Substring SPOJ - LCS(后缀自动机)
作者:互联网
题意:求两个串的最长公共子串长度
思路:对a串建sam,b串跑
#include <bits/stdc++.h> using namespace std; #define ll long long const int maxn=250010; char s[maxn]; struct Suffix_Automaton{ //basic int nxt[maxn*2][26], fa[maxn*2], l[maxn*2]; int last,cnt; int match_len[maxn*2], match_times[maxn*2]; int label[maxn*2], mx[maxn*2]; Suffix_Automaton(){ clear(); } void clear(){ last =cnt=1; fa[1]=l[1]=0; memset(nxt[1],0,sizeof nxt[1]); for (int i=0;i<maxn*2;i++) match_len[i] = INT_MAX; } void init(char *s){ while (*s){ add(*s-'a');s++; } } void add(int c){ int p = last; int np = ++cnt; memset(nxt[cnt],0,sizeof nxt[cnt]); l[np] = l[p]+1;last = np; while (p&&!nxt[p][c])nxt[p][c] = np,p = fa[p]; if (!p)fa[np]=1; else{ int q = nxt[p][c]; if (l[q]==l[p]+1)fa[np] =q; else{ int nq = ++ cnt; l[nq] = l[p]+1; memcpy(nxt[nq],nxt[q],sizeof (nxt[q])); fa[nq] =fa[q];fa[np] = fa[q] =nq; while (nxt[p][c]==q)nxt[p][c] =nq,p = fa[p]; } } } void run(char * s,int Label){ vector<pair<int,int> > nodes; vector<int> a,b; int now = 1, len = 0; while (*s){ int ch = *s - 'a'; while (now != 1 and !nxt[now][ch]){ now = fa[now]; len = l[now]; } if (nxt[now][ch]){ now = nxt[now][ch]; len ++; } nodes.push_back(make_pair(now,len)); a.push_back(now); s ++; } auto cmp = [&](int x,int y){ return l[x] > l[y]; }; sort(a.begin(),a.end(),cmp); a.erase(unique(a.begin(),a.end()),a.end()); for (int x : a){ int temp = x; while (temp != 1 and label[temp] != Label){ b.push_back(temp); label[temp] = Label; mx[temp] = 0; temp = fa[temp]; } } sort(b.begin(),b.end(),cmp); for (auto pr : nodes){ mx[pr.first] = max(mx[pr.first],pr.second); } for (int x : b){ mx[fa[x]] = max(mx[fa[x]],l[fa[x]]); match_len[x] = min(match_len[x],mx[x]); match_times[x] ++; } } ll calc(int tot_times){ ll tot = 0; for (int i = 1;i <= cnt;i ++){ if (match_times[i] == tot_times){ tot += max(0,match_len[i] - l[fa[i]]); } } return tot; } int lcs(char *s) { int n=strlen(s); int cur=1; int ans=0; int y=0; for(int i=0;i<n;i++) { int c=s[i]-'a'; if(!nxt[cur][c]) { while(cur&&!nxt[cur][c]) cur=fa[cur]; y=l[cur]+1; } else { y++; } cur=cur?nxt[cur][c]:1; if(cur==1) y=0; ans=max(y,ans); } return ans; } }sam; int main() { scanf("%s",&s); int n=strlen(s); sam.init(s); scanf("%s",s); printf("%d\n",sam.lcs(s)); }
标签:LCS,temp,int,len,Substring,SPOJ,maxn,now,mx 来源: https://www.cnblogs.com/2462478392Lee/p/13781906.html