POJ2774:Long Long Message

问两个串的最长公共子串,n<=100000。

SAM可以直接搞当然SA哈希都可以。。类似于KMP的做法,如果沿parent边走要顺势修改匹配位置。

 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 }
View Code

 

posted @ 2017-12-07 12:07  Blue233333  阅读(167)  评论(0编辑  收藏  举报