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\) 值进行划分. 显然,对于每一 ...
随机推荐
- 如何更改Java括号中的默认对齐
(1)在使用程序猿非常Java当大括号的排列有感就是它的不那么整齐! 很多人不知道为什么会这样: public class HelloWorld{ pulic static void main(Str ...
- client多线程
1.多线程对象 对象可以是多线程访问,线程可以在这里分为两类: 为完成内部业务逻辑的创建Thread对象,线程需要访问对象. 使用对象的线程外部对象. 进一步假设更精细的划分.业主外螺纹成线等线,. ...
- redis(Remote Dictionary Server)
redis的简介和使用 简介 redis(Remote Dictionary Server)是一种Nosql技术,它是一个开源的高级kv存储和数据结构存储系统,它经常被拿来和Memcached相比 ...
- linux内核数据包转发流程(三)网卡帧接收分析
[版权声明:转载请保留出处:blog.csdn.net/gentleliu.邮箱:shallnew*163.com] 每一个cpu都有队列来处理接收到的帧,都有其数据结构来处理入口和出口流量,因此,不 ...
- hdu 4912 Paths on the tree(树链拆分+贪婪)
题目链接:hdu 4912 Paths on the tree 题目大意:给定一棵树,和若干个通道.要求尽量选出多的通道,而且两两通道不想交. 解题思路:用树链剖分求LCA,然后依据通道两端节点的LC ...
- 设计模式之前奏(UML类图)
原文:设计模式之前奏(UML类图) 本人菜菜一个,最近一直在博客园游走闲逛,看到了各种技术,各种各种…….便看到了大话设计模式这本书,下了电子版的看了看第一章,感觉相当不错,不仅通俗易懂,而且与实际案 ...
- Jquery在线咨询地址
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type=&quo ...
- Web层的搭建
Web层的搭建 前言:好久没更新博客了,每天被该死的业务缠身,今天正好一个模块完成了,继续来完善我们的代码.之前的六篇完成了领域层.应用层.以及基础结构层的部分代码,这篇打算搭建下UI层的代码. DD ...
- 简单搜索dfs, 简单的修剪搜索
选择最合适的语言做一个项目是非常重要的.但,熟练的掌握自己的武器,这也是非常重要的. ========================================================= ...
- T-SQL性能调整——信息收集
原文:T-SQL性能调整--信息收集 IO信息(自服务器启动开始) --Database IO analysis WITH IOFORDATABASE AS ( SELECT DB_NAME(VFS. ...