ABC375 D题题解

相对于 C 题较为简单。

O(n3)O(n^3) 做法

暴力枚举三点位置,不可通过。

O(n2)O(n^2) 做法

枚举最前与最后点,贡献为中间点的个数,不可通过,但是很好的启发

O(n)O(n)O(nlogn)O(n\log n) 做法

枚举最前与最后点,贡献为中间点的个数

这是刚才我们的想法,我们要快速求出这个东西,先用两个数组存储当前为 sis_i 的字符下标之和与当前为 sis_i 的字符数量。

为了方便,称当前该字符出现次数为 tottot,当前字符下标之和为 sumsum,当前下标为 ii

当遇到一个字符时,答案会增加 tot×itot\times i 吗?不是,因为前面的点并不一定全在最开始的地方。

当遇到一个字符时,答案会增加 tot×isumtot\times i-sum 吗?也不是,因为中间字符个数要减一。

当遇到一个字符时,答案会增加 tot×(i1)sumtot\times(i-1)-sum 吗?对了!

Code:

#include<bits/stdc++.h>
using namespace std;
string s;
long long n, ans;
map<char, long long> sum, tot;
int main(){
	cin >> s; n = s.size();
	for(long long i = 0; i < n; i ++){
		ans += max((i - 1) * tot[s[i]] - sum[s[i]], 0LL);//当然不能小于零
		sum[s[i]] += i; tot[s[i]] ++;
	}
	cout << ans;
	return 0;
}

其中 map<char, long long> sum, tot; 可以使用数组代替,进一步将 O(nlogn)O(n\log n) 代码优化至 O(n)O(n)

posted on 2024-10-12 22:15  zhangzirui66  阅读(7)  评论(0)    收藏  举报  来源

导航