输入输出样例
示例 1
输入
ababc
输出
28
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
这题和子串分值其实是一道题。想看子串分值的同学可以转到这里:
区别在哪呢?在于如果出现了...a...a...a...类似于这种的东西我们如何计数多个相同的字符,比如只包含前两个a的所有子串有多少个?只包含后面两个a的子串有多少个?
我们可以这样来看记...a...a...a...从左到右的间隔长度依次为x,y,z,m,那么只包含第一个a的子串有多少个呢,正如子串分值中所求是xy个(xy这里有一些细节,比如左边界是-1,右边界是s.size,这些细节在编程中去体会),那只包含前两个的呢?是x*y,同理三个四个,最后我们知道只包含第一个a的子串且将重复的计算在内就是x*(y+z+m),这就是总数,同理计算第二个a,我们左边取y,意思是从上一个边界取起,试想一下,如果我们包含了上一个a,我们肯定会与上一次的统计计算重复。之后也很简单了,第二个算的就是y*(z+m)。规律就出来了。
我们还是像子串分值里面一样求出L[i],对每一个位置i,计算(L[i]-i)*(s.size()-i),这就是子串分值和。
代码如下所示:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100010;
int L[N];
int pos[30];
int main()
{
// 请在此输入您的代码
string s;
cin>>s;
// int len=s.size();
memset(pos,-1,sizeof(pos));
for(int i=0;i<s.size();++i)
{
int index=s[i]-'a';
L[i]=pos[index];
pos[index]=i;
}
ll ans=0;
for(int i=0;i<s.size();++i)
{
ans+=(i-L[i])*(s.size()-i);
}
cout<<ans<<endl;
return 0;
}