#include <iostream> #include <vector> #include <string> using namespace std; int main() { int n; string s; cin >> n >> s; vector<vector<int>> prefix_counts(n + 1, vector<int>(26, 0)); vector<int> current(26, 0); for (int i = 0; i < n; ++i) { char ch = s[i]; prefix_counts[i] = current; current[ch - 'a']++; } prefix_counts[n] = current; vector<vector<int>> suffix_counts(n, vector<int>(26, 0)); current = vector<int>(26, 0); for (int i = n - 1; i >= 0; --i) { char ch = s[i]; suffix_counts[i] = current; current[ch - 'a']++; } long long ans = 0; for (int i = 0; i < n; ++i) { char c = s[i]; int idx = c - 'a'; int pre_total = i; int pre_c_count = prefix_counts[i][idx]; int sum = pre_total - pre_c_count; int suf_c_count = suffix_counts[i][idx]; ans += (long long)sum * suf_c_count; } cout << ans << endl; return 0; }
https://www.nowcoder.com/discuss/727521113110073344
思路:
- 前缀数组: prefix_counts 数组保存每个位置之前的各字符出现次数。通过遍历字符串,逐步更新当前字符计数并保存到前缀数组中。
- 后缀数组: suffix_counts 数组保存每个位置之后的各字符出现次数。通过逆序遍历字符串,逐步更新当前字符计数并保存到后缀数组中。
- 计算贡献: 对于每个位置,计算其作为中间字符时的有效子序列数量,即前导不同字符数乘以后续相同字符数,累加到总结果中。