CF50B Choosing Symbol Pairs 题解
Content
给定一个字符串 \(s\),求有多少对是相同的(包括自己和自己这一对,\((x,y)\) 和 \((y,x)\) 是不相同的一对)。
数据范围:\(1\leqslant |s|\leqslant 10^5\)。
Solution
这道题目需要证明一个东西:如果有 \(n\) 个相同的字母,那么它们之间相同的对数就是 \(n^2\)。
证明:因为自己和自己算做一对,所以先有 \(n\) 对。
同时,又因为两两之间配对可以算作两对,\(n\) 个字符两两配对就一共会有 \(\dfrac{n(n-1)}{2}\times2=n(n-1)\) 对。
所以,加起来一共会有 \(n+n(n-1)=n+n^2-n=n^2\) 对。
证毕。
因此,我们需要统计一个字符出现的次数 \(n\),那么它对于这个对数的贡献就是 \(n^2\),对于每个字符的贡献,我们累加起来,这样得出的结果就是我们题目的答案了。
建议开两个 \(\texttt{map}\),一个 \(\texttt{map}\) 用来存储每个字符出现的次数,另一个 \(\texttt{map}\) 则用来判断是否有重复(这样就不会重复计算)。
Code
#include <cstdio>
#include <algorithm>
#include <map>
#include <iostream>
using namespace std;
string s;
map<char, long long> a, vis;
long long sum;
int main() {
cin >> s;
for(int i = 0; i < s.size(); ++i) a[s[i]]++;
for(int i = 0; i < s.size(); ++i) {
if(!vis[s[i]]) {
sum += a[s[i]] * a[s[i]];
vis[s[i]] = 1;
}
}
printf("%lld\n", sum);
return 0;
}