菜鸡一枚,这题是看唯一写了题解的大佬做的,因为他写的不够详细,所以在此写了一篇题解
c++代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
typedef long long ll;
char str[N];
int pre[N]; // pre[i]记录第几个位置内的字母上一次出现的位置
int nex[N]; // nex[i]记录第i个位置的字母下一次出现的位置
int h[26]; // 每一次更新a-z字母出现的下标(下标从1开始,表示第几个位置)
ll ans;
int main(){
scanf("%s",str + 1); // 从下标为1开始输入字符串
int len = strlen(str + 1);
for(int i=1;i<=len;i++){
int t = str[i] - 'a'; // 用下标表示字母 a-0 b-1 c-2 d-3 e-4.....
pre[i] = h[t]; // z这里有个技巧可以看到有两个t每次循环都在记录某一个字母新出现的位置,而这里恰好是在h[t]更新之前把h[t]赋给pre[i]-----记录第几个位置内的字母上一次出现的位置
h[t] = i;
}
for(int i=0;i<26;i++) h[i] = len+1;
for(int i=len;i>=1;i--){
int t = str[i] - 'a';
nex[i] = h[t]; // 这里同理,这里每个位置都会更新,如果没有出现下一个同样的字母,默认下一个为len+1
h[t] = i;
}
for(int i=1;i<=len;i++)
{
ans+=(ll)(i-pre[i])*(nex[i]-i);
}
cout<<ans<<endl;
return 0;
}
为什么要从下标为1开始输入字符串
哇哇哇感谢大佬懂了懂了
函数第一个for循环没有用吧
第二句写错了
已修改