Problem B. Vera and Banquet
后缀数据结构
GYM
题目大意
给出长度为N的字符串,围成一个圈。可以顺时针或逆时针取出子串。问,有多少种不同的子串?
数据范围: 2≤N≤50000 字符只包含小写字母
解答
求一个字符串的子串种类,是经典问题了,后缀数组和后缀自动机均可做。
加上圈的条件,如果只是顺时针,可以copy一遍,统计长度 ≤N 的种类。
对于逆时针,在copy一遍的基础上,对称过去,中间加一个特殊字符。
所以,最后就是对一个长度为 4∗N+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=14∗N+1(min(4∗N+1−sa[i]+1,n)−min(hei[i],N))−N∗(N+1)2
AC代码 (后缀数组)