Problem Description
035 now faced a tough problem,his english teacher gives him a string,which consists with n lower case letter,he must figure out how many substrings appear at least twice,moreover,such apearances can not overlap each other.
Take aaaa as an example.”a” apears four times,”aa” apears two times without overlaping.however,aaa can’t apear more than one time without overlaping.since we can get “aaa” from [0-2](The position of string begins with 0) and [1-3]. But the interval [0-2] and [1-3] overlaps each other.So “aaa” can not take into account.Therefore,the answer is 2(“a”,and “aa”).
 
Input
The input data consist with several test cases.The input ends with a line “#”.each test case contain a string consists with lower letter,the length n won’t exceed 1000(n <= 1000).
 
Output
For each test case output an integer ans,which represent the answer for the test case.you’d better use int64 to avoid unnecessary trouble.
 
Sample Input
aaaa
ababcabb
aaaaaa
#
 
Sample Output
2
3
3

emmmmmmm,WA了,因为L和R错了;

找L和R需要全部字母插入后拓扑排序求出。

如果不,maxlen(v)+1 < maxlen(x)的时候会拆点,导致x点和拆出的y点L,R出错。

。。。好像是个很弱智的问题,勿喷,我知道错啦。

和HDU4416差不多,写法上一个从0开始,一个从1开始。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
const int maxn=;
int tot,slink[*maxn],trans[*maxn][],maxlen[*maxn];
char str[*maxn];
int R[maxn],L[maxn],last;
long long ans;
void init()
{
ans=tot=;
last=;
memset(trans[],-,sizeof(trans[]));
memset(L,,sizeof(L));
memset(R,,sizeof(R));
slink[]=-; maxlen[]=;
}
void add_char(int pos,char chr)
{
bool ww=false;
int c=chr-'a',nq=;
int p=last,np=++tot;
maxlen[np]=maxlen[p]+;
memset(trans[np],-,sizeof(trans[np]));
while(p!=-&&trans[p][c]==-) trans[p][c]=np,p=slink[p];
if(p==-) slink[np]=;
else
{
int q=trans[p][c];
if(maxlen[q]!=maxlen[p]+)
{
nq=++tot;
memcpy(trans[nq],trans[q],sizeof(trans[q]));
maxlen[nq]=maxlen[p]+;
slink[nq]=slink[q];
slink[np]=slink[q]=nq;
while(p!=-&&trans[p][c]==q) trans[p][c]=nq,p=slink[p];
L[nq]=R[nq]=pos;
ww=true;
}
else slink[np]=q;
}
last=np;
for(;np>;np=slink[np]){
if(!L[np]) L[np]=pos;
R[np]=pos;
}
}
int main() {
while(~scanf("%s",str)){
if(str[]=='#') return ;
init();
int N=strlen(str);
for(int i=; i<N; i++) add_char(i+,str[i]);
for(int i=;i<=tot;i++) {
if(R[i]-L[i]>=maxlen[i]) ans+=maxlen[i]-maxlen[slink[i]];
else ans+=max(,R[i]-L[i]-maxlen[slink[i]]+);
}
printf("%lld\n",ans);
}
}

别人的AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lng long long
using namespace std; const int maxn = + ;
char s[maxn];
int str[maxn], len;
struct suffixautomaton
{
int ch[maxn][], pre[maxn], val[maxn], top[maxn];
int c[maxn];
int l[maxn], r[maxn];
int sz, last; void init() { pre[] = -; last = ; sz = ; memset(ch[], , sizeof(ch[])); } void insert(int x)
{
int p = last, np = sz++; last = np;
memset(ch[np], , sizeof(ch[np]));
val[np] = val[p] + ;
while(p != - && ch[p][x] == )
{
ch[p][x] = np;
p = pre[p];
}
if(p == -) pre[np] = ;
else
{
int q = ch[p][x];
if(val[q] == val[p] + )
pre[np] = q;
else
{
int nq = sz++;
memcpy(ch[nq], ch[q], sizeof(ch[q]));
val[nq] = val[p] + ;
pre[nq] = pre[q];
pre[q] = pre[np] = nq;
while(p != - && ch[p][x] == q) { ch[p][x] = nq; p = pre[p]; }
}
}
} void solve()
{
memset(c, , sizeof(c));
for(int i = ; i < sz; ++i) c[val[i]] += ;
for(int i = ; i <= len; ++i) c[i] += c[i - ];
for(int i = ; i < sz; ++i) top[--c[val[i]]] = i;
for(int i = ; i < sz; ++i) { l[i] = len + ; r[i] = -; }
for(int i = ; ; i = ch[i][str[val[i]]])
{
l[i] = r[i] = val[i];
if(val[i] == len) break;
}
for(int i = sz - ; i > ; --i)
{
int u = top[i];
l[pre[u]] = min(l[pre[u]], l[u]);
r[pre[u]] = max(r[pre[u]], r[u]);
}
lng ans = ;
for(int i = ; i < sz; ++i)
{
if(r[i] - l[i] > val[pre[i]])
{
lng tmp = min(val[i], r[i] - l[i]);
ans += (tmp - val[pre[i]]);
}
}
printf("%I64d\n", ans);
}
}sam; int main()
{
while(~scanf("%s", s) && s[] != '#')
{
len = strlen(s);
sam.init();
for(int i = ; s[i]; ++i)
{
str[i] = s[i] - 'a';
sam.insert(str[i]);
}
sam.solve();
}
return ;
}

地址:http://blog.csdn.net/cool_Fires/article/details/9732475

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

  1. Boring counting HDU - 3518 后缀自动机

    题意: 对于给出的字符串S, 长度不超过1000, 求其中本质不同的子串的数量, 这些子串满足在字符串S中出现了至少不重合的2次 题解: 将串放入后缀自动机中然后求出每一个节点对应的子串为后缀的子串出 ...

  2. HDU 5343 MZL's Circle Zhou 后缀自动机+DP

    MZL's Circle Zhou Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. JQuery 操作 checkbox 二次赋值无效 attr ----> prop

    CheckBox .attr('checked',false);  Chrome和火狐第二次点击无效. 然后解决了把attr 改成了 prop 以后操作属性的时候各位记下,用prop 因为大家用的都是 ...

  2. 【转】ModelAndView 学习

    http://blog.csdn.net/wavaya/article/details/6185226 ModelAndView 类别就如其名称所示,是代表了Spring Web MVC程式中呈现画面 ...

  3. 在运行myeclipse10注册机时,显示找不到com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel这个包

    在win7下安装MyEclipse10.安装完成之后运行注册机,总是提示classnotfond显示找不到com.sun.java.swing.plaf.nimbus.NimbusLookAndFee ...

  4. LeetCode:二叉树的锯齿形层次遍历【103】

    LeetCode:二叉树的锯齿形层次遍历[103] 题目描述 给定一个二叉树,返回其节点值的锯齿形层次遍历.(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行). 例如:给定二叉树 ...

  5. SpringMVC:学习笔记(3)——REST

    SpringMVC:学习笔记(3)——REST 了解REST风格 按照传统的开发方式,我们在实现CURD操作时,会写多个映射路径,比如对一本书的操作,我们会写多个URL,可能如下 web/delete ...

  6. Python 5 面对对象编程

    面向对象编程: 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强...” 面向过程编程 ...

  7. CSS 命名里面有大学问

    其实迟迟不敢开始写关于样式里布局方面的心得, 因为大多数人眼中,哪需要管那么多,只需要最终效果达到了就行了呗. 然而,即使是如今国内外顶级大牛也不敢说自己是个优秀的 CSS 工程师. 一般大公司都是 ...

  8. U-Boot中支持USB

    转载: http://blog.csdn.net/qiurihuanghua/article/details/6234832 今天查看了一下在P4080DS板子的U-Boot中支持USB,主要是加入U ...

  9. Go 语言为Fibonacci函数实现Read方法

    Go语言非常灵活,只要为对象实现了相应的方法就可以把他看成实现了某个接口,类似于Durk Type, 为Fibonacci实现Read方法,就可以像读取文件一样,去读取下一个Fibonacci值. 示 ...

  10. JQuery 操作 iframe

    JQuery访问iframe内的元素 $("iframe#Main", top.document).contents().find("#id"); JQuery ...