codeforces GYM 101431B (后缀数据结构)

Problem B. Vera and Banquet

后缀数据结构 GYM

题目链接

题目大意

给出长度为N的字符串,围成一个圈。可以顺时针或逆时针取出子串。问,有多少种不同的子串?

数据范围: 2N50000 字符只包含小写字母

解答

求一个字符串的子串种类,是经典问题了,后缀数组和后缀自动机均可做。

加上圈的条件,如果只是顺时针,可以copy一遍,统计长度 N 的种类。

对于逆时针,在copy一遍的基础上,对称过去,中间加一个特殊字符。

所以,最后就是对一个长度为 4N+1 的字符串做后缀数组或后缀自动机,计算长度 N 的种类并减去包含中间特殊字符的字符串种类(这个比较好算,包含特殊字符的子串都没有重复,可以直接算)。

如果包含特殊字符的长度是len,那么该长度就有len种子串(特殊字符分别放在位置1..len处)

所以包含特殊字符的子串是 1+2+...+N=N(N+1)2

我的做法是用后缀自动机,建完自动机后,结点有cnt个,start结点的编号是1。

最终公式如下:

Ans=i=start+1cnt(min(val[i],n)min(val[par[i]],n))N(N+1)2

AC代码 (后缀自动机)

如果用后缀数组的话,公式也是类似的,改一下就可以了。

Ans=i=14N+1(min(4N+1sa[i]+1,n)min(hei[i],N))N(N+1)2

AC代码 (后缀数组)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值