CF1800F 题解

Solution

考虑转化题目条件,因为要求字符串恰好有 25 个字符,所以考虑枚举没出现过的字符,令其为 k。再令 fi,p 表示第 i 个字符串 p 字符出现次数的奇偶,于是题目条件即为:

  • fi,k=fj,k=0
  • fi,p+fj,pmod2=1

于是考虑用一个 226 的桶或 bitset 表示出每个字符串,即如果 fi,pmod2=1numnum+2p,把 num 放入桶,统计答案的时候将 fi,pmod2=0j 加入 num 即可,时间复杂度为 O(nV2)V26

#include<bits/stdc++.h>
#define ll long long 
#define x first 
#define y second 
#define il inline 
#define debug() puts("-----") 
using namespace std; 
typedef pair<int,int> pii; 
const int N=2e5+10,M=26; 
int n; 
int f[N][M]; 
string s[N]; 
int mp[1<<M]; 
bool st[N][M]; 
il void work(){ 
    cin>>n; ll ans=0; 
    for(int i=1;i<=n;i++){ 
        cin>>s[i]; 
        for(int j=0;j<M;j++) f[i][j]=0; 
        for(int j=0;j<s[i].size();j++) f[i][s[i][j]-'a']++,st[i][s[i][j]-'a']=true; 
    } for(int k=0;k<M;k++){ 
        for(int i=1;i<=n;i++){ 
            if(st[i][k]) continue; int num=0; 
            for(int j=0;j<M;j++) if(f[i][j]&1) num+=(1<<j); 
            mp[num]++;  
        } for(int i=1;i<=n;i++){ 
            if(st[i][k]) continue; int num=0; 
            for(int j=0;j<M;j++) if(j!=k&&(!(f[i][j]&1))) num+=(1<<j); 
            ans+=1ll*mp[num]; 
        } for(int i=1;i<=n;i++){ 
            if(st[i][k]) continue; int num=0; 
            for(int j=0;j<M;j++) if(f[i][j]&1) num+=(1<<j); 
            mp[num]--; 
        } 
    } printf("%lld\n",ans/2); 
} 
signed main(){ 
    int T=1; 
    while(T--) work(); return 0; 
} 
posted @   Celestial_cyan  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示