写出来了,但是感觉前两年写肯定写不出来,所以做个记录~
题目描述
对于一个字符串 SS,我们定义 SS 的分值 f(S)f(S) 为 SS 中出现的不同的字符个数。例如 f("aba")=2,f("abc")=3,f("aaa")=1f("aba")=2,f("abc")=3,f("aaa")=1。
现在给定一个字符串 S[0...n−1]S[0...n−1](长度为 nn),请你计算对于所有 SS 的非空子串 S[i...j](0≤i≤j<n)S[i...j](0≤i≤j<n),f(S[i...j])f(S[i...j]) 的和是多少。
输入描述
输入一行包含一个由小写字母组成的字符串 SS。
其中,1≤n≤1051≤n≤105。
输出描述
输出一个整数表示答案。
输入输出样例
示例 1
输入
ababc
输出
28
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
int ans=0;//最终答案
int len=0;//字符串0~i-1中,以字符串i-1结尾的子串的分值和
//记录第一次出现的位置,和最后一次出现的位置
int sta[26],endd[26];
signed main(){
//暴力能拿一定分
//直接暴力
string s;
cin>>s;
for(int i=0;i<26;i++){
sta[i]=-1;
endd[i]=-1;
}
for(int i=0;i<s.size();i++){ //i作为终点
if(sta[s[i]-'a']==-1){ //没有出现过
sta[s[i]-'a']=i;
endd[s[i]-'a']=i;
//i之前所有的数据
len+=i+1;
ans+=len;
}
else{
len+=(i-endd[s[i]-'a']);
ans+=len;
endd[s[i]-'a']=i;//更新记录最后出现的位置
}
}
cout<<ans<<endl;
}