CF1800F 题解

Solution

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

  • \(f_{i,k}=f_{j,k}=0\)
  • \(f_{i,p}+f_{j,p} \bmod 2=1\)

于是考虑用一个 \(2^{26}\) 的桶或 bitset 表示出每个字符串,即如果 \(f_{i,p} \bmod 2=1\)\(num \gets num+2^p\),把 \(num\) 放入桶,统计答案的时候将 \(f_{i,p} \bmod 2=0\)\(j\) 加入 \(num\) 即可,时间复杂度为 \(O(nV^2)\)\(V\)\(26\)

#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 @ 2024-03-07 13:36  Celestial_cyan  阅读(15)  评论(0)    收藏  举报