问题:

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. 如何通过js处理相同时间的信息整合到一起的问题

    背景: 倘若后台已经处理好了时间,也就是 今天,昨天,显示具体日期,那么通过js如何写才能调整成如下形式呢? 今天: 第一条数据 第二条数据 昨天: 第一条数据 第二条数据 具体时间: 第一条数据 第 ...

  2. centOS6.2 最小安装下的无线网络配置

    一.安装wireless_tools,http://www.linuxfromscratch.org/blfs/view/svn/basicnet/wireless_tools.html 二.vi / ...

  3. maven;cargo;仓库

    [说明]又到晚上九点了,不得不加快进度,首先就是日报.今天上午在服务器搭建maven,下午完成了一个maven web项目,晚上改错找maven配置问题(因为想装jetty和cargo) 一:今日完成 ...

  4. (比赛)B - 棋盘问题(dfs)

    B - 棋盘问题 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%lld & %llu Practice POJ ...

  5. WCF基础之Message类

    客户端和服务端的通信都是通过接收和发送的Message实例建立起来的,大多数情况我们通过服务协定.数据协定和消息协定来构造传入和传出消息的. 一般什么时候使用Message类呢?不需要将消息序列化或者 ...

  6. ASP跳出FOR循环

    由于ASP不能使用GOTO语句,我在FOR循环中加入一个FOR循环,若需要跳出,即退出最里面那个FOR循环. DEMO: <%dim aa = 0for i = 1 to 10    for j ...

  7. Django使用富文本编辑器

    1.下载kindeditor 网址:http://kindeditor.net/demo.php2.解压到项目中 地址:\static\js\kindeditor-4.1.103.删除没用的文件 例如 ...

  8. valuestack,stackContext,ActionContext.之间的关系以及action的数据在页面中取得的方法

     转自:http://blog.csdn.net/quechao123/article/details/4406148 1.三者之间的关系如下图所示: 2.action的数据在页面中取得的方法 在st ...

  9. linux 9 -- 交互式使用Bash Shell

    二十二. 交互式使用Bash Shell:     1.  用set命令设置bash的选项:     下面为set主要选项的列表及其表述: 选项名 开关缩写 描述 allexport -a 打开此开关 ...

  10. linux 11 -- mount,umount

    Linux 文件系统是一个以 / 为根的大树,我们在不同的设备和分区上都有文件系统.我们如何处理这种明显的不一致性?根 (/) 文件系统是在初始化过程中挂载的.您创建的其他每个文件系统在挂载 在挂载点 ...