POJ2774:Long Long Message
问两个串的最长公共子串,n<=100000。
SAM可以直接搞当然SA哈希都可以。。类似于KMP的做法,如果沿parent边走要顺势修改匹配位置。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<stdlib.h> 5 //#include<iostream> 6 //#include<assert.h> 7 //#include<time.h> 8 using namespace std; 9 10 int n; 11 #define maxn 200011 12 char s[maxn],p[maxn]; 13 14 struct samnode 15 { 16 int ch[26],pre; 17 int pos; 18 samnode() {memset(ch,0,sizeof(ch)); pre=0;} 19 }; 20 struct SAM 21 { 22 samnode a[maxn];int last,size; 23 SAM() {last=0;a[0].pos=0;size=0;a[0].pre=-1;} 24 int idx(char c) {return c-'a';} 25 void insert(char c,int p) 26 { 27 int id=idx(c);int x=++size; 28 a[x].pos=p; 29 int y=last; 30 for (;y!=-1 && !a[y].ch[id];y=a[y].pre) a[y].ch[id]=x; 31 last=x; 32 if (y==-1) a[x].pre=0; 33 else 34 { 35 if (a[a[y].ch[id]].pos==a[y].pos+1) a[x].pre=a[y].ch[id]; 36 else 37 { 38 int z=a[y].ch[id],w=++size; 39 a[w]=a[z]; 40 a[w].pos=a[y].pos+1; 41 a[z].pre=a[x].pre=w; 42 for (;y!=-1 && a[y].ch[id]==z;y=a[y].pre) a[y].ch[id]=w; 43 } 44 } 45 } 46 }sam; 47 int main() 48 { 49 scanf("%s",s+1);n=strlen(s+1); 50 scanf("%s",p);int lp=strlen(p); 51 for (int i=0;i<lp;i++) sam.insert(p[i],i+1); 52 int now=0;int ans=0; 53 for (int i=1,cnt=0;i<=n;i++) 54 { 55 while (now && !sam.a[now].ch[s[i]-'a']) now=sam.a[now].pre,cnt=sam.a[now].pos; 56 if (sam.a[now].ch[s[i]-'a']) cnt++,now=sam.a[now].ch[s[i]-'a']; 57 else cnt=0,now=0; 58 ans=max(ans,cnt); 59 } 60 printf("%d\n",ans); 61 return 0; 62 }