Description
有一个文件被破坏了,可是值得庆幸的是,只是文件的顺序被打乱了。文件仅包含大小写的拉丁字母以及逗号,句号和叹号。为了尽快修复,请你找出有多少个至少出现两次的子串。
比如字符串abbabc,子串”a”,”b”,”ab”分别出现了2次,3次,2次。
Solution
这是一道 SA 的题目
对于排好序的每个后缀
- abbabc
- abc
- babc
- bbabc
- bc
- c
做到第
i
个后缀时,我们只考虑以这一后缀开头为开头的子串
显然
然而可能有的字符已经算过了,要减掉重复的
对于每一种算过的子串,只保留一个,其他的都要减掉,那就把每一次的
height[i−1]
减掉就好(如果这一次有的话)
所以每一次就减 max(0,height[i]−height[i−1])
下面只贴主程序
Code
int main()
{
scanf("%s",st+1);
n=strlen(st+1);
int i;
fo(i,1,n)
{
int cm=st[i];
m=max(m,cm);
}
findSA();
findheight();
int ans=0;
fo(i,2,n) ans+=max(0,height[i]-height[i-1]);//关键
cout<<ans;
}