Codeforces Round 855 (Div. 3) F

1|0F

核心思路

首先我们可以知道的是只要满足了条件2和条件3必然会满足条件1.因为奇数和奇数的乘积一定是奇数。这一个比较显而易见的性质。

然后就是我们需要思考我们得使用什么方式来表示我们的条件2和条件3的状态呢。这里就运用到了状态压缩的知识,也就是我们使用二进制序列来表示我们的状态,因为总共的状态也只有1<<26.也就是只需要表示26个字母就好了。

集合定义

a[i]i

b[i]i

接下来就是怎么预处理a数组和b数组呢,其实不难发现a数组的处理可以采用位或操作,而b数组可以采用异或操作。这个自己模拟下就好了。

因为题目只需要25个字母,所以我们可以枚举缺失的哪个字母。再就是从前往后枚举我们的字符串,假设当前枚举的是字符串i,先看他的是不是只缺少一个字符,也就是a[i]的状态,再就是先搞出来我们目标的b[i],再看那些字符串是不是有对应的b[i].

这些每个合法一半的状态可以采用cnt数组来存储。

// Problem: F. Dasha and Nightmares // Contest: Codeforces - Codeforces Round 855 (Div. 3) // URL: https://codeforces.com/contest/1800/problem/F // Memory Limit: 512 MB // Time Limit: 4000 ms // // Powered by CP Editor (https://cpeditor.org) #define _CRT_SECURE_NO_WARNINGS #include<bits/stdc++.h> using namespace std; typedef long long LL; #define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define NO {puts("NO") ; return ;} #define YES {puts("YES") ; return ;} #define endl "\n" const int N=1e6+10; int n; int a[N]; int b[N]; int cnt[1<<26]; signed main() { IOS; cin>>n; for(int i=1;i<=n;i++) { string s; cin>>s; for(int j=0;j<s.size();j++) { a[i] |= (1 << (s[j] - 'a')), b[i] ^= (1 << (s[j] - 'a')); } } LL ans=0; for(int i=0;i<26;i++) { int S=((1<<26)-1)-(1<<i); for(int j=1;j<=n;j++) { if(!(a[j]>>i&1)) { cnt[b[j]]++; ans+=cnt[S^b[j]]; } } for(int j=1;j<=n;j++) { if(!(a[j]>>i&1)) cnt[b[j]]--; } } cout<<ans<<endl; return 0; }

__EOF__

本文作者肖英豪
本文链接https://www.cnblogs.com/xyh-hnust666/p/17188229.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   努力的德华  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示