F. Dasha and Nightmares(hash)

题目链接:Problem - F - Codeforces

题意:

给n(1<n<2e5)个字符串,总的长度不超过5e6,判断多少对字符串对<i,j>组合后,满足长度为奇数,不同字母刚好有25种,且每个字母个数为奇数。

思路:

用哈希表法,用状态压缩,把a∼z映射到0∼25。对于第i个字符串si,定义ai为si中出现的字母的状态,如果字母c出现过,那么ai的第c位应该为1,否则为0。定义bi为每个字母出现次数奇偶性的状态,如果字母c出现了奇数次,那么bi的第c位应该为1,否则为0。

对于一个正确的字符串s,应该满足ai中有25个1,bi中也有25个1,并且1的位置应该是一样的,

通过枚举c,一共有26个,来看看拼接字符串中少了哪个字母,对应ai=bi=2^26-1-2^c。然后对于每个c,枚举每一个字符串i,si对应的ai的第c位应该为0,才能满足题意。所以看看i前面有多少个

j,满足aj的第c位为0,且有bj或与bi=2^26-1-2^c.

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
typedef long long int ll;
using namespace std;
const int N = 2e5 + 10;
ll a[N], b[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    map<ll, ll>mp;
    ll res = 0;
    int i;
    for (i = 1; i <= n; i++)
    {
        string s;
        cin >> s;
        for (auto c : s)
        {
            a[i] ^= 1 << (c - 'a');//记录奇数字符的个数
            b[i] |= 1 << (c - 'a');//记录有多少个字符
        }
    }
    int j;
    for (j = 0; j < 26; j++)
    {
        ll sta = ((1 << 26) - 1) ^ (1 << j);//记录第几个字符
        mp.clear();
        for (i = 1; i <= n; i++)
        {
            if (!(b[i] >> j & 1))//说明b的第j位元素不是奇数的话
            {
                res += mp[sta ^ a[i]];//加上与a[i]偶数元素相对于的缺少的字符串数列
                mp[a[i]]++;//更新mp中的相应奇数的a[i]的数量;
            }
        }
    }
    cout << res << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值