SPOJ1811 LCS - Longest Common Substring
阿新 • • 發佈:2018-12-22
傳送門[洛谷]
SAM板子題?(可惜我還是不會)
大概就是能匹配就一直往下匹配
不能匹配就跳parent 調到能匹配為止 跳到根了就重新開始
最開始太蠢了非要寫遞迴版 寫著寫著發現不知道我要寫啥了T^T 果斷換迴圈。。
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define inf 20021225 #define ll long long #define mxn 250010 using namespace std; struct node{int ch[26],fa,len;}t[mxn*4]; int poi,rt,lt,ans,n;char ch[mxn]; int id(char ch){return ch-'a';} void insert(int c) { int p=lt,np=lt=++poi; t[np].len=t[p].len+1; for(;p&&!t[p].ch[c];p=t[p].fa) t[p].ch[c]=np; if(!p){t[np].fa=rt;return;} int q=t[p].ch[c]; if(t[q].len==t[p].len+1){t[np].fa=q;return;} int nq=++poi;t[nq].len=t[p].len+1; memcpy(t[nq].ch,t[q].ch,sizeof(t[q].ch)); t[nq].fa=t[q].fa; t[q].fa=t[np].fa=nq; for(;p&&t[p].ch[c]==q;p=t[p].fa) t[p].ch[c]=nq; } void find() { int pos=rt,cur=0; for(int i=1;i<=n;i++) { int tmp=id(ch[i]); ans=max(ans,cur); if(t[pos].ch[tmp]) cur++,pos=t[pos].ch[tmp]; else { for(;pos&&!t[pos].ch[tmp];pos=t[pos].fa); if(pos) cur=t[pos].len+1,pos=t[pos].ch[tmp]; else cur=0,pos=rt; } } ans=max(ans,cur); } int main() { scanf("%s",ch+1);n=strlen(ch+1); rt=lt=++poi; for(int i=1;i<=n;i++) insert(id(ch[i])); scanf("%s",ch+1);n=strlen(ch+1); find(); printf("%d\n",ans); return 0; }