CF1045I Palindrome Pairs 题解
题目分析
首先得出两个串加在一起构成回文的要求:最多只有
想也很好想,同个字母两两对应,对应不了的那个放中间就行。
然后我们发现每个字符串只需要存储每个字母的数量的奇偶性
满足要求的对数可以分成两种情况考虑:
- 每个字母总共都是偶数个。
观察下列式子:
可以发现只有二进制数相等的两个字符串可以构成这种情况,开一个数组记录每个二进制数的个数。然后这其中任选两个都能构成回文,即贡献为
- 有且仅有一个字母为奇数个。
也很容易得出两个字符串的二进制仅有一个位不同。那么也只需要开一个哈希记录每一个二进制数可以被“匹配”的数量(“匹配”即为仅有一个位不同)。然后贡献为每个字符串对应的二进制数被“匹配”的个数。
最后答案为上述两种情况的和。
代码
#include<bits/stdc++.h>
using namespace std;
unordered_map<long long,long long> mp,ct;
vector<long long> v;
long long n,x,res;
int main()
{
scanf("%lld",&n);
for (int e = 1;e <= n;e++)
{
x = 0;//将字符串存为一个二进制数
string s;cin >> s;
for (int i = 0;i < s.size();i++) x ^= (1 << (s[i]-'a'));//存第s[i]位
v.push_back(x);
for (int i = 0;i < 26;i++)
if (((x >> i) & 1) == 0)
ct[(x+(1 << i))]++; //第i位不同的匹配
mp[x]++;
}
for (auto e:mp) res += e.second*(e.second-1)/2; //偶数的情况贡献为cn2
for (auto t:v) res += ct[t]; // 可以被匹配
cout << res <<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现