试题H:子串分值和
【问题描述】
对于一个字符串 S,我们定义 S 的分值 f(S) 为 S 中出现的不同的字符个数。
例如 f(”aba”)=2,f(”abc”)=3,f(”aaa”)=1。 现在给定一个字符串 S[0..n−1](长度为 n),
请你计算对于所有 S 的非空 子串 S[i..j](0≤i≤j<n),f(S[i..j]) 的和是多少。
【输入格式】
输入一行包含一个由小写字母组成的字符串 S
【输出格式】
输出一个整数表示答案。
【样例输入】
ababc
【样例输出】
28
【样例说明】
子串 f值
a 1
ab 2
aba 2
abab 2
ababc 3
b 1
ba 2
bab 2
babc 3
a 1
ab 2
abc 3
b 1
bc 2
c 1
思路:
对于每一个子串的分值,只有第一次出现在内的字符才会对该子串有贡献。例如子串“ababc”其内有贡献的是字符abc。那么假设数组last[i]表示字符i上一次出现的位置,则字符s[i]有贡献的子字符串为[last[i]+1,i]和[i,n]组成的子字符串,共有(i-last[i])*(n-i+1)。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
String str =cin.next();
int[] a = new int[30];
long ans = 0;
int n = str.length();
str = " " + str;
for(int i=1;i<=n;++i) {
ans+=(i-a[str.charAt(i)-'a'])*(long)1*(n-i+1);
a[str.charAt(i)-'a']=i;
}
System.out.println(ans);
}
}