问题:

Amateur astronomers Tom and Bob try to find radio broadcasts of extraterrestrial civilizations in the air. Recently they received some strange signal and represented it as a word consisting of small letters of the English alphabet. Now they wish to decode the signal. But they do not know what to start with.
      They think that the extraterrestrial message consists of words, but they cannot identify them. Tom and Bob call a subword of the message a potential word if it has at least two non-overlapping occurrences in the message.

For example, if the message is “abacabacaba”, “abac” is a potential word, but “acaba” is not because two of its occurrences overlap.
      Given a message m help Tom and Bob to find the number of potential words in it.

Input

      Input file contains one string that consists of small letters of the English alphabet. The length of the message doesn’t exceed 10 000.

Output

      Output one integer number — the number of potential words in a message.

Sample Input

abacabacaba

Sample Output

15

题意:

求字符串里的不相交重复字串的个数和。

思路;

后缀自动机:记录每个状态的最先出现和最后一次出现的位置,就可以判断是否出现了多次,以及是否相交。(116ms)

后缀数组:。。。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<memory>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=;
char chr[maxn];
int Head[maxn],Lates[maxn],Now;
struct SAM
{
int sz,Last,ch[maxn][],slink[maxn],maxlen[maxn],ans;
int c[maxn],pos[maxn],num[maxn];
void init()
{
Last=sz=;Head[]=Lates[]=;ans=;
memset(ch[],,sizeof(ch[]));
memset(Lates,,sizeof(Lates));
memset(Head,,sizeof(Head));
}
void add(int x)
{
int np=++sz,p=Last;Last=np;num[np]=;
Head[np]=Now;Lates[np]=Now; memset(ch[np],,sizeof(ch[np]));
maxlen[np]=maxlen[p]+;
while(p&&!ch[p][x]) ch[p][x]=np,p=slink[p];
if(!p) slink[np]=;
else {
int q=ch[p][x];
if(maxlen[q]==maxlen[p]+) slink[np]=q;
else {
int nq=++sz; num[nq]=;
memcpy(ch[nq],ch[q],sizeof(ch[q])); Head[nq]=Head[q];Lates[nq]=Lates[q];
slink[nq]=slink[q],slink[np]=slink[q]=nq;
maxlen[nq]=maxlen[p]+;
while(p&&ch[p][x]==q) ch[p][x]=nq,p=slink[p];
}
}
while(np>) Lates[np]=Now,np=slink[np];
}
void solve()
{
for(int i=;i<=sz;i++) {
int dis=Lates[i]-Head[i];
int mi=min(dis,maxlen[i]);
if(mi>=maxlen[slink[i]]) ans+=mi-maxlen[slink[i]];
}
printf("%d\n",ans);
}
};
SAM sam;
int main()
{
sam.init(); int l;
scanf("%s",chr); l=strlen(chr);
for(Now=;Now<l;Now++) sam.add(chr[Now]-'a'); sam.solve();
return ;
}

也可以刷新完了再跟新最后一次出现的位置(拓扑排序)(4ms)(优化一下居然时间排名第一了。。。)

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<memory>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=;
char chr[maxn];
int Head[maxn],Lates[maxn],Now;
struct SAM
{
int sz,Last,ch[maxn][],slink[maxn],maxlen[maxn],ans;
int c[maxn],pos[maxn],num[maxn];
void init()
{
Last=sz=;Head[]=Lates[]=;ans=;
memset(ch[],,sizeof(ch[]));
memset(Lates,,sizeof(Lates));
memset(Head,,sizeof(Head));
}
void add(int x)
{
int np=++sz,p=Last;Last=np;num[np]=;
Head[np]=Now;Lates[np]=Now; memset(ch[np],,sizeof(ch[np]));
maxlen[np]=maxlen[p]+;
while(p&&!ch[p][x]) ch[p][x]=np,p=slink[p];
if(!p) slink[np]=;
else {
int q=ch[p][x];
if(maxlen[q]==maxlen[p]+) slink[np]=q;
else {
int nq=++sz; num[nq]=;
memcpy(ch[nq],ch[q],sizeof(ch[q])); Head[nq]=Head[q];Lates[nq]=Lates[q];
slink[nq]=slink[q],slink[np]=slink[q]=nq;
maxlen[nq]=maxlen[p]+;
while(p&&ch[p][x]==q) ch[p][x]=nq,p=slink[p];
}
}
//while(np>1) Lates[np]=Now,np=slink[np];
}
void sort()
{
for(int i=;i<=sz;i++) c[i]=;
for(int i=;i<=sz;i++) c[maxlen[i]]++;
for(int i=;i<=sz;i++) c[i]+=c[i-];
for(int i=;i<=sz;i++) pos[c[maxlen[i]]--]=i;
for(int i=sz;i>=;i--) Lates[slink[pos[i]]]=max(Lates[pos[i]],Lates[slink[pos[i]]]);
}
void solve()
{ ans=;
for(int i=;i<=sz;i++) {
int dis=Lates[i]-Head[i];
int mi=min(dis,maxlen[i]);
if(mi>=maxlen[slink[i]]) ans+=mi-maxlen[slink[i]];
}
printf("%d\n",ans);
}
};
SAM sam;
int main()
{
sam.init();int l;
scanf("%s",chr);l=strlen(chr);
for(Now=;Now<l;Now++) sam.add(chr[Now]-'a');
sam.sort();sam.solve();
return ;
}

ACdream1430SETI(后缀自动机)的更多相关文章

  1. BZOJ 后缀自动机四·重复旋律7

    后缀自动机四·重复旋律7 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的 ...

  2. 【Codeforces235C】Cyclical Quest 后缀自动机

    C. Cyclical Quest time limit per test:3 seconds memory limit per test:512 megabytes input:standard i ...

  3. 【hihocoder#1413】Rikka with String 后缀自动机 + 差分

    搞了一上午+接近一下午这个题,然后被屠了个稀烂,默默仰慕一晚上学会SAM的以及半天4道SAM的hxy大爷. 题目链接:http://hihocoder.com/problemset/problem/1 ...

  4. 【BZOJ-3998】弦论 后缀自动机

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2018  Solved: 662[Submit][Status] ...

  5. HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)

    Reincarnation Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  6. hihoCoder 后缀自动机三·重复旋律6

    后缀自动机三·重复旋律6 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi ...

  7. hihoCoder #1445 : 后缀自动机二·重复旋律5

    #1445 : 后缀自动机二·重复旋律5 时间限制:10000ms 单点时限:2000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数 ...

  8. 数据结构:后缀自动机 WJMZBMR讲稿的整理和注释

    链接放在这里,有点难理解,至少我个人是的. 后缀自动机是一种有限状态自动机,其功能是识别字符串是否是母串的后缀.它能解决的问题当然不仅仅是判断是不是后缀这种事,跟字符串的连续子串有关的问题都可以往这个 ...

  9. 【SPOJ】7258. Lexicographical Substring Search(后缀自动机)

    http://www.spoj.com/problems/SUBLEX/ 后缀自动机系列完成QAQ...撒花..明天or今晚写个小结? 首先得知道:后缀自动机中,root出发到任意一个状态的路径对应一 ...

随机推荐

  1. poj1861 最小生成树 prim &amp; kruskal

    // poj1861 最小生成树 prim & kruskal // // 一个水题,为的仅仅是回味一下模板.日后好有个照顾不是 #include <cstdio> #includ ...

  2. 怎样过滤跨站恶意脚本攻击(XSS)

    什么是XSS? XSS(Cross Site Scripting),即跨站脚本攻击,是一种常见于web application中的计算机安全漏洞.XSS通过在用户端注入恶意的可运行脚本,若服务器端对用 ...

  3. 九度OJ 1203:IP地址 (字符串处理)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3038 解决:1496 题目描述: 输入一个ip地址串,判断是否合法. 输入: 输入的第一行包括一个整数n(1<=n<=500) ...

  4. iptables的用例

    iptables书写思路顺序 1.协议 icmp 2.哪个功能和目标:过滤,拒绝 3.数据包流向:外到内 4.哪个链适合:越早越好,INPUT 5.源地址和目标地址 练习1.禁止某些主机或网络访问本机 ...

  5. [转]How Hash Algorithms Work

    来看看SHA-1到底是如何工作的 http://www.metamorphosite.com/one-way-hash-encryption-sha1-data-software

  6. node-sass 安装失败的解决措施[转]

    转自:http://blog.csdn.net/nzb329/article/details/51935236 在编译一个项目的时候,一直报错 后来发现是因为node-sass没有装成功, 最终的解决 ...

  7. 使VS自动生成代码注释

    1.注释模板位置C:\Program Files\Microsoft Visual Studio 11.0\Common7\IDE\ItemTemplatesCache 里面有各种脚本的模板 2.找到 ...

  8. POJ - 3414 Pots 【BFS】

    题目链接 http://poj.org/problem?id=3414 题意 给出两个杯子 容量分别为 A B 然后给出C 是目标容量 有三种操作 1 将一个杯子装满 2.将一个杯子全都倒掉 3.将一 ...

  9. JAVA事件监听机制与实现

    事件监听机制的实现:参考图:事件模型_ActionEvent 为了节省资源,系统无法对某个事件进行实时的监听.故实现的机制是当发生某个事件后,处理代码将被自动运行,类似钩子一般.(回调函数) 事件有许 ...

  10. VNC服务安装、配置与使用

    原帖地址: http://blog.itpub.net/519536/viewspace-607549/ 该文档配置环境是RHEL,不同系统可能会有差别,本人测试过centos,ubuntu 1.确认 ...