输入和初始化:
读取字符串 str,并从索引 1 开始存储(C++ 中字符串索引从 0 开始,但这里为了简化计算,从 1 开始)。
n 存储字符串的长度。
数组 l[i] 存储字符 str[i] 上一次出现的位置。
数组 r[i] 存储字符 str[i] 下一次出现的位置。
数组 p 用于临时存储每个字符最近一次出现的位置,初始化为 0。
计算 l[i] 数组:
遍历字符串,对于每个字符 str[i],计算它上一次出现的位置 l[i],并更新 p[t] 为当前位置 i。
重置 p 数组:
将 p 数组所有元素重置为 n + 1,为计算 r[i] 数组做准备。这表示任何字符在字符串末尾之后的位置是 n + 1。
计算 r[i] 数组:
从字符串末尾开始向前遍历,对于每个字符 str[i],计算它下一次出现的位置 r[i],并更新 p[t] 为当前位置 i。
计算结果:
初始化结果 res 为 0。
遍历字符串,对于每个字符 str[i],计算以该字符为唯一字符的子串数量,并累加到 res 中。这个数量等于 (i - l[i]) * (r[i] - i)。
输出结果:
打印结果 res。
`#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int n;char s[N];int l[N],r[N],p[26];
int main()
{
scanf("%s",s+1);
n=strlen(s+1);
for(int i=1;i<=n;i++)
{
int t=s[i]-'a';//映射
l[i]=p[t];
p[t]=i;
}
for(int i=0;i<26;i++)p[i]=n+1;
for(int i=n;i;i--)
{
int t=s[i]-'a';
r[i]=p[t];
p[t]=i;
}
long long res=0;
for(int i=1;i<=n;i++)
{
res+=(long long)(i-l[i])*(r[i]-i);
}
printf("%lld\n", res);
return 0;
}`