POJ2774 后缀自动机&后缀数组

http://poj.org/problem?id=2774

题目大意就是给两个字符串,求最长公共子串。好像可以哈希切掉,但是为了练一练后缀数组以及学一学后缀自动机,我用不同方法终于A掉了这道题。

后缀数组:就是求出height数组然后扫一遍,求出满足条件的最大值(满足条件是指height所指的两个后缀要没有公共部分),是后缀数组的水题

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 char tmp[100005],s[200005];
 6 int n,sa[200005],rak[200005],height[200005],t[200005],t2[200005],c[300];
 7 void build_sa(int m)
 8 {
 9     int *x=t,*y=t2,p;
10     for(int i=0;i<m;i++)c[i]=0;
11     for(int i=0;i<n;i++)c[x[i]=s[i]]++;
12     for(int i=0;i<m;i++)c[i]+=c[i-1];
13     for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
14     for(int k=1;k<=n;k<<=1)
15     {
16         p=0;
17         for(int i=n-k;i<n;i++)y[p++]=i;
18         for(int i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;
19         for(int i=0;i<m;i++)c[i]=0;
20         for(int i=0;i<n;i++)c[x[y[i]]]++;
21         for(int i=0;i<m;i++)c[i]+=c[i-1];
22         for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
23         swap(x,y);
24         p=1;x[sa[0]]=0;
25         for(int i=1;i<n;i++)
26         x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++;
27         if(p>=n)break;
28         m=p;
29     }
30 }
31 void printsa()
32 {
33     puts("");
34     for(int i=0;i<n;i++)
35     {
36         char *ss=s+sa[i];
37         while(*ss)putchar(*ss++);
38         puts("");
39     }
40 }
41 void get_height()
42 {
43     for(int i=0;i<n;i++)rak[sa[i]]=i;
44     int k=0;
45     for(int i=0;i<n;i++)
46     {
47         if(k)k--;
48         if(rak[i]==0){height[rak[i]]=k;continue;}
49         int j=sa[rak[i]-1];
50         while(s[i+k]==s[j+k])k++;
51         height[rak[i]]=k;
52     }
53 }
54 int main()
55 {
56     int mid;
57     while(scanf("%s",tmp)>0)
58     {
59         memset(s,0,sizeof(s));
60         mid=strlen(tmp);
61         tmp[mid]=‘$‘;
62         strcat(s,tmp);
63         scanf("%s",tmp);
64         tmp[strlen(tmp)+1]=‘\0‘;
65         tmp[strlen(tmp)]=‘#‘;
66         strcat(s,tmp);
67         n=strlen(s);
68         build_sa(130);
69         //printsa();
70         get_height();
71         int ans=0;
72         for(int i=1;i<n;i++)if(height[i]>ans&&((sa[i-1]<mid&&sa[i]>mid)||(sa[i-1]>mid&&sa[i]<mid)))ans=height[i];
73         printf("%d\n",ans);
74     }
75     return 0;
76 }

后缀自动机:基本上是一道模板题,用第一个字符串建好后缀自动机,再用第二个字符串匹配。。。感觉和AC自动机差不多(感觉数组写法比指针写法好看多了)

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int N=101000;
 7 char s[N],t[N];
 8 int last,son[N<<1][30],dep[N<<1],pre[N<<1],lens,lent,tot,rt;
 9 void SAM(int alp)
10 {
11     int u=last;dep[++tot]=dep[last]+1;
12     last=tot;
13     while(u&&!son[u][alp])son[u][alp]=last,u=pre[u];
14     if(!u)pre[last]=rt;
15     else
16     {
17         int v=son[u][alp];
18         if(dep[v]==dep[u]+1)pre[last]=v;
19         else
20         {
21             dep[++tot]=dep[u]+1;
22             int nv=tot;
23             memcpy(son[nv],son[v],sizeof(son[nv]));
24             pre[nv]=pre[v];pre[v]=pre[last]=nv;
25             while(u&&son[u][alp]==v)son[u][alp]=nv,u=pre[u];
26         }
27     }
28 }
29 int solve()
30 {
31     int cur,tmp=0,ret=0;
32     cur=rt=last=++tot;
33     for(int i=1;i<=lens;i++)SAM(s[i]-‘a‘);
34     for(int i=1;i<=lent;i++)
35     {
36         if(son[cur][t[i]-‘a‘]){cur=son[cur][t[i]-‘a‘];tmp++;}
37         else
38         {
39             while(cur&&!son[cur][t[i]-‘a‘])cur=pre[cur];
40             if(!cur)cur=rt,tmp=0;
41             else tmp=dep[cur]+1,cur=son[cur][t[i]-‘a‘];
42         }
43         ret=max(ret,tmp);
44     }
45     return ret;
46 }
47 int main()
48 {
49     scanf("%s%s",s+1,t+1);
50     lens=strlen(s+1);lent=strlen(t+1);
51     printf("%d\n",solve());
52 }
时间: 2024-08-24 14:47:20

POJ2774 后缀自动机&后缀数组的相关文章

SPOJ705 Distinct Substrings (后缀自动机&amp;后缀数组)

Given a string, we need to find the total number of its distinct substrings. Input T- number of test cases. T<=20;Each test case consists of one string, whose length is <= 1000 Output For each test case output one number saying the number of distinc

康复计划#1 再探后缀自动机&amp;后缀树

本篇口胡写给我自己这样的东西都忘光的残废选手 以及那些刚学SAM,看了其他的一些东西并且没有完全懵逼的人 (初学者还是先去看有图的教程吧,虽然我的口胡没那么好懂,但是我觉得一些细节还是讲清楚了的) 大概是重复一些有用的想法和性质,用以加深印象吧-如果可以的话希望也能理解得更透彻一点- 1.如何设计出一个后缀自动机? 现在用的SAM并不是本来就在那里的,要比较深入地理解,就不能只从验证它对不对的角度考虑,而要考虑为什么它是这个样子. 要一个能够接受后缀的有限状态机,并不用像现在的SAM那样弄,比如

后缀自动机/后缀树

只是笔记罢了,不要看 关于DAWG: 见紫书P390 把后缀自动机上所有节点都设为接受态就形成DAWG,可以接受一个字符串的所有子串. 一个子串的end-set是它在原串w中出现位置(从1开始编号)的右端点集合. 在DAWG中,end-set相同的子串属于同一个状态. 原因没原因,这应该算定义吧? 任意两个节点的end-set要么不相交,要么是包含关系. 原因:在DAWG上走一步,当前end-set的变化是将原end-set中各个元素+1(要去掉超出字符串长度的元素),然后拆分成1个或多个新en

BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机 后缀自动机 字符串

https://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机是一种可以处理好多字符串的一种数据结构(不像后缀自动机只有处理一到两种的时候比较方便). 后缀自动机可以说是一种存子串的缩小点数的trie树,广义后缀自动机就是更改了一下塞点的方式让它可以塞多个子串. 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<

后缀自动机(SAM)学习指南

*在学习后缀自动机之前需要熟练掌握WA自动机.RE自动机与TLE自动机* 什么是后缀自动机 后缀自动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂度构造,能够接受一个字符串所有后缀的自动机. 它最早在陈立杰的 2012 年 noi 冬令营讲稿中提到. 在2013年的一场多校联合训练中,陈立杰出的 hdu 4622 可以用 SAM 轻松水过,由此 SAM 流行了起来. 一般来说,能用后缀自动机解决的问题都可以用后缀数组解决.但是后缀自动机也拥有自己的优点. 1812.

后缀自动机(SAM)

*在学习后缀自动机之前需要熟练掌握WA自动机.RE自动机与TLE自动机* 什么是后缀自动机 后缀自动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂度构造,能够接受一个字符串所有后缀的自动机. 它最早在陈立杰的 2012 年 noi 冬令营讲稿中提到. 在2013年的一场多校联合训练中,陈立杰出的 hdu 4622 可以用 SAM 轻松水过,由此 SAM 流行了起来. 一般来说,能用后缀自动机解决的问题都可以用后缀数组解决.但是后缀自动机也拥有自己的优点. 1812.

后缀自动机详解 -----转载

转载于:http://blog.csdn.net/qq_35649707/article/details/66473069 原论文(俄文)地址:suffix_automata 后缀自动机 后缀自动机(单词的有向无环图)——是一种强有力的数据结构,让你能够解决许多字符串问题. 例如,使用后缀自动机可以在某一字符串中搜索另一字符串的所有出现位置,或者计算不同子串的个数——这都能在线性 时间内解决. 直觉上,后缀自动机可以被理解为所有子串的简明信息.一个重要的事实是,后缀自动机以压缩后的形式包含了一个

后缀自动机小结 (spoj 8222)

后缀自动机理解关键点: 1. 根到任意一个结点都可以形成S的一个子串,并且S的所有子串都可以通过这种方式形成; 2. 到达该节点是所有路径就是一个right集合,一个拥有相同后缀的right集合; 3. 设某子串为str,这后缀自动机读入str后能到达的状态为right(str),即str在S中出现的位置的集合; 4. 假设node[b].fa = a,则状态a可以代替状态b进行识别. 附图: 更详细的资料: http://wenku.baidu.com/view/90f22eec551810a

poj2774 Long Long Message(后缀数组or后缀自动机)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Case Time Limit: 1000MS Description The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes t