AcWing 2868. 子串分值
原题链接
中等
1.暴力
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
char ch[N];
int st[30];
int get(int start, int len) {
int res = 0;
memset(st, 0, sizeof st);
for(int i = start; i < start + len; i ++) {
int x = ch[i] - 'a';
st[x] ++;
}
for(int i = 0; i < 30; i ++)
if(st[i] == 1)
res ++;
return res;
}
int main() {
scanf("%s", ch);
int n = strlen(ch);
long long res = 0;
for(int i = 0; i < n; i ++) {
for(int len = 1; i + len <= n; len ++) {
int cnt = get(i, len);
res += cnt;
}
}
printf("%lld\n", res);
return 0;
}
2.贡献法
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
char ch[N];
int l[N], r[N], p[30];
int main() {
scanf("%s", ch + 1);
int n = strlen(ch + 1);
for(int i = 1; i <= n; i ++) {
int t = ch[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 = ch[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;
}