HDOJ 3518 Boring counting
SAM基本操作 拓扑寻求每个节点 最左边的出现left,最右边的出现right,已经有几个num ......
对于每个出现两次以上的节点。对其所相应的一串子串的长度范围 [fa->len+1,len] 和其最大间距 right-left比較
就可以......
Boring counting
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1552 Accepted Submission(s): 637
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”).
aaaa
ababcabb
aaaaaa
#
2
3
3
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int CHAR=26,maxn=1100; struct SAM_Node
{
SAM_Node *fa,*next[CHAR];
int len,id,pos;
SAM_Node(){}
SAM_Node(int _len)
{
len=_len;
fa=0; memset(next,0,sizeof(next));
}
}; SAM_Node SAM_node[maxn*2],*SAM_root,*SAM_last;
int SAM_size; SAM_Node *newSAM_Node(int len)
{
SAM_node[SAM_size]=SAM_Node(len);
SAM_node[SAM_size].id=SAM_size;
return &SAM_node[SAM_size++];
} SAM_Node *newSAM_Node(SAM_Node *p)
{
SAM_node[SAM_size]=*p;
SAM_node[SAM_size].id=SAM_size;
return &SAM_node[SAM_size++];
} void SAM_init()
{
SAM_size=0;
SAM_root=SAM_last=newSAM_Node(0);
SAM_node[0].pos=0;
} void SAM_add(int x,int len)
{
SAM_Node *p=SAM_last,*np=newSAM_Node(p->len+1);
np->pos=len; SAM_last=np;
for(;p&&!p->next[x];p=p->fa)
p->next[x]=np;
if(!p)
{
np->fa=SAM_root;
return ;
}
SAM_Node *q=p->next[x];
if(q->len==p->len+1)
{
np->fa=q;
return ;
}
SAM_Node *nq=newSAM_Node(q);
nq->len=p->len+1;
q->fa=nq; np->fa=nq;
for(;p&&p->next[x]==q;p=p->fa)
p->next[x]=nq;
} char str[maxn];
int len,c[maxn],L[maxn*2],R[maxn*2],num[maxn*2];
SAM_Node *top[maxn*2]; int main()
{
while(scanf("%s",str)!=EOF)
{
if(str[0]=='#') break;
SAM_init();
len=strlen(str);
for(int i=0;i<len;i++)
SAM_add(str[i]-'a',i+1); memset(c,0,sizeof(c)); memset(top,0,sizeof(top));
memset(L,0,sizeof(L)); memset(R,0,sizeof(R)); memset(num,0,sizeof(num)); ///get tupo sort
for(int i=0;i<SAM_size;i++)
c[SAM_node[i].len]++;
for(int i=1;i<=len;i++)
c[i]+=c[i-1];
for(int i=0;i<SAM_size;i++)
top[--c[SAM_node[i].len]]=&SAM_node[i]; ///get L,R,num
SAM_Node *p=SAM_root;
for(;p->len!=len;p=p->next[str[p->len]-'a'])
{
num[p->id]=1;
L[p->id]=R[p->id]=p->len;
}
for(int i=SAM_size-1;i>=0;i--)
{
p=top[i];
if(L[p->id]==0&&R[p->id]==0)
{
L[p->id]=R[p->id]=p->pos;
}
if(p->fa)
{
SAM_Node *q=p->fa;
num[q->id]+=num[p->id];
if(L[q->id]==0||L[q->id]>L[p->id])
L[q->id]=L[p->id];
if(R[q->id]==0||R[q->id]<R[p->id])
R[q->id]=R[p->id];
}
}
int ans=0;
for(int i=1;i<SAM_size;i++)
{
int ma=SAM_node[i].len;
int mi=SAM_node[i].fa->len+1;
int le=R[SAM_node[i].id]-L[SAM_node[i].id];
if(le>=ma)
ans+=ma-mi+1;
else if(le>mi)
ans+=le-mi+1;
}
printf("%d\n",ans);
}
return 0;
}
版权声明:本文博客原创文章。博客,未经同意,不得转载。
HDOJ 3518 Boring counting的更多相关文章
- HDOJ 题目3518 Boring counting(后缀数组,求不重叠反复次数最少为2的子串种类数)
Boring counting Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- 后缀数组 --- HDU 3518 Boring counting
Boring counting Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=3518 Mean: 给你一个字符串,求:至少出 ...
- HDU 3518 Boring counting
题目:Boring counting 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3518 题意:给一个字符串,问有多少子串出现过两次以上,重叠不能算两次 ...
- 【HDOJ】3518 Boring Counting
后缀数组2倍增可解. #include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 10 ...
- hdu 3518 Boring counting 后缀数组基础题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...
- HDU 3518 Boring counting(后缀数组,字符处理)
题目 参考自:http://blog.sina.com.cn/s/blog_64675f540100k9el.html 题目描述: 找出一个字符串中至少重复出现两次的字串的个数(重复出现时不能重叠). ...
- hdu 3518 Boring counting 后缀数组LCP
题目链接 题意:给定长度为n(n <= 1000)的只含小写字母的字符串,问字符串子串不重叠出现最少两次的不同子串个数; input: aaaa ababcabb aaaaaa # output ...
- hdu 3518 Boring counting 后缀数组
题目链接 根据height数组的性质分组计算. #include <iostream> #include <vector> #include <cstdio> #i ...
- hdu 3518 Boring counting 后缀数组 height分组
题目链接 题意 对于给定的字符串,求有多少个 不重叠的子串 出现次数 \(\geq 2\). 思路 枚举子串长度 \(len\),以此作为分界值来对 \(height\) 值进行划分. 显然,对于每一 ...
随机推荐
- Linux C编程语言学习材料
C语言作为最基础的编程语言,30年虚弱的患病率. 无论是准备做 PHP/Java/Python/Golang 开发学习.C语言都是基础的,我们非常多基础非常小的互联网执行的开源软件服务都是C语言构筑, ...
- 【转】HLSL基础
原文地址http://blog.csdn.net/chpdirect1984/article/details/1911622 目录 前言 1.HLSL入门 1.1什么是着色器 1.2什么是HLSL 1 ...
- 你的第一个AngularJS应用--教程二:基架、建立和測试的工具
介绍 有非常多可用的工具能够帮助你开发AngularJS 应用,那些非常复杂的框架不在我的讨论范围之中,这也是我開始这系列教程的原因. 在第一部分,我们掌握了AngularJS框架的基本结构,开发了第 ...
- Java就业前景怎么样?学了后好找工作吗?
不知道大家对Java就业前景了解多少.随着信息化的发展.IT培训受倒了越来越多人的追捧.在开发领域,JAVA培训成为了很多人的首选!JAVA应用广泛.JAVA培训就业前景良好. 眼下.尽管JAVA人才 ...
- Java 审查基调
1.& 与 &&的差别 两个都有逻辑与的功能. 可是所不同的是.当&两边的表达式不是boolean类型的时候,&具有位与的功能:&&是短路与,当 ...
- java使用Base64编码和解码的图像文件
1.编码和解码下面的代码示例看: import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import j ...
- MD5和Base64
一. 简述 MD5: 全称为message digest algorithm 5(信息摘要算法), 能够进行加密, 可是不能解密, 属于单向加密, 通经常使用于文件校验 Base64: 把随意序列的8 ...
- XUtils骨架HttpUtils采用Get总是返回请求解决问题的相同信息
如需转载请注明出处:http://blog.csdn.net/itas109 版本号:Xutils 2014年11月11日 下载地址:https://github.com/wyouflf/xUtils ...
- 加密解密工具类(Java,DES)
一个Java版的DES加密工具类,能够用来进行网络传输数据加密,保存password的时候进行加密. import java.security.Key; import java.security.sp ...
- 性能优化——统计信息——SQLServer自动更新和自动创建统计信息选项
原文:性能优化--统计信息--SQLServer自动更新和自动创建统计信息选项 原文译自:http://www.mssqltips.com/sqlservertip/2766/sql-server-a ...