子串分值和
问题描述
对于一个字符串 ,我们定义 的分值 为 中出现的不同的字符个数。例如 “aba”,“abc”, “aaa”。
在给定一个字符串 (长度为 ),请你计算对于所有 的非空子串 ,的和是多少。
输入格式
输入一行包含一个由小写字母组成的字符串 。
输出格式
输出一个整数表示答案。
样例输入
ababc
样例输出
28
样例说明
子串 f值
a 1
ab 2
aba 2
abab 2
ababc 3
b 1
ba 2
bab 2
babc 3
a 1
ab 2
abc 3
b 1
bc 2
c 1
这篇代码主要是从网上借鉴的,但是当时看到这个算法的时候,读不懂他的意思,后来搞懂了,所以将我的理解和要点写在了注释之中。
我的代码:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main(){
//使用longlong的原因是分值和过大
long long pre[30]={0};//记录上一次这个字符出现的位置
string str;
cin>>str;
long long len=str.size();
str="0"+str;
long long sum=0;
for(long long i=1;i<=len;i++){
sum+=(i-pre[str[i]-'a'])*(len-i+1);//计算当前这个字符对整个字符串有多少贡献,如果它还没出现过,那就是对整个字符串都有贡献,不然它只对上一次出现之后的排列做出了贡献
//假如i=1,且第一次出现,则sum+=1*它后面的长度。假如i=6,且这个字符在i=3,出现,则sum+=3*上一次出现之后的字符长度。opababc,则第二个a做出贡献的字符串为babc的排列,在babc之前的排列已经被第一个a做过了贡献。
pre[str[i]-'a']=i;
}
cout<<sum;
return 0;
}