题意:给你 2e5 个字符串,总长不超过 5e6 ,输出多少对字符串两两组合之后,满足 1.长度是奇数 2.不同的字母恰好25个 3.每个字母出现次数都是奇数;
分析:线性枚举,统一算贡献,发现当枚举过去的时候,没后效性,所以只要算出枚举到当前情况之前的累计,发现没法直接查询,这里就要想到用 hash 压缩表示状态;然后对于每一个位置是空的要单独算;
void slv(){
unordered_map<int, int> mp[26];
vector<int> tag(26);
for (int i = 0; i < 26; i++) {
tag[i] = (((1 << 26) - 1) ^ (1 << i));
}
ll ans = 0;
int n; cin >> n;
for (int j = 0; j < n; j++) {
vector<int> cnt(26);
string s; cin >> s;
for (auto x : s) {
cnt[x - 'a']++;
}
int now = 0;
for (int i = 0; i < 26; i++) {
if (cnt[i] & 1) {
now |= (1 << i);
}
}
for (int i = 0; i < 26; i++) {
int tmp = tag[i] ^ now;
if (cnt[i] == 0 && mp[i].count(tmp)) {
ans += mp[i][tmp];
}
}
for (int i = 0; i < 26; i++) {
if (cnt[i] == 0) mp[i][now]++;
}
}
cout << ans << '\n';
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
slv();
}