[JZOJ1598]文件修复

Description

有一个文件被破坏了,可是值得庆幸的是,只是文件的顺序被打乱了。文件仅包含大小写的拉丁字母以及逗号,句号和叹号。为了尽快修复,请你找出有多少个至少出现两次的子串。
比如字符串abbabc,子串”a”,”b”,”ab”分别出现了2次,3次,2次。

Solution

这是一道 SA 的题目

对于排好序的每个后缀

  • abbabc
  • abc
  • babc
  • bbabc
  • bc
  • c

做到第 i 个后缀时,我们只考虑以这一后缀开头为开头的子串
显然Ans应该加上 height[i]
然而可能有的字符已经算过了,要减掉重复的
对于每一种算过的子串,只保留一个,其他的都要减掉,那就把每一次的 height[i1] 减掉就好(如果这一次有的话)

所以每一次就减 max(0,height[i]height[i1])

下面只贴主程序

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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值