javaee论坛

普通会员

225648

帖子

344

回复

358

积分

楼主
发表于 2019-11-03 06:40:29 | 查看: 625 | 回复: 2

定义字符串的循环次数为串长除以最短循环节的长度,给定一个字符串,求子串中最大的循环次数。

分析ababababacabababaclcp=7,ans=4babababacbababaclcp=6,ans=4

如果给定了循环节长度L和起始位置x,那么lcp(x,x+L)/L+1就是一个可用的循环次数。

ababababxabababxlcp=6,ans=4babababxbababxlcp=5,ans=3

考虑没法正好枚举成功的情况,怎么办呢,向前找?

abcabcabcabcxabcabcabcxlcp=9,ans=4bcabcabcabcxabcabcabcxlcp=8,ans=3cabcabcabcxabcabcabcxlcp=7,ans=3

只要给位置x减去L-lcp%L,再求一次lcp即可,因为更多一个的出现位置只可能出现在此处。

做法

枚举循环节长度LLL,对于所有LLL的倍数xxx,求所有ans=lcp(x,x+L)/L+1ans=lcp(x,x+L)/L+1ans=lcp(x,x+L)/L+1,再给xxx减去L−lcp(x,x+L)L-lcp(x,x+L)%LL−lcp(x,x+L),重新求一次ansansans,取最大值。

单次求lcplcplcp的复杂度O(1)O(1)O(1),总复杂度O(nlogn)O(nlogn)O(nlogn)

代码charstr[M];scanf("%s",str);intn=strlen(str);SuffixArray::build(str,n,127);intans=0;for(intlen=1;len<=n;++len){for(intid=0;id<n-len;id+=len){intlcp=SuffixArray::lcp(id,id+len);ans=max(ans,lcp/len+1);intnid=id-(len-lcp%len);if(nid>=0)ans=max(ans,SuffixArray::lcp(nid,nid+len)/len+1);}}cout<<ans<<endl;

普通会员

0

帖子

337

回复

348

积分
沙发
发表于 2019-11-13 15:53:18

谢谢楼主分享

普通会员

0

帖子

316

回复

318

积分
板凳
发表于 2023-08-23 07:16:58

我最喜欢回复人少的贴子了,如果贴子沉了,我就会觉得是自己弄沉的,非常有成就感!如果贴子火了,那我有占了前排,这简直是稳赚不赔的生意嘛

您需要登录后才可以回帖 登录 | 立即注册

触屏版| 电脑版

技术支持 历史网 V2.0 © 2016-2017