codeforces1045I. Palindrome Pairs(hash)

                                                                                  I. Palindrome Pairs

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

After learning a lot about space exploration, a little girl named Ana wants to change the subject.

Ana is a girl who loves palindromes (string that can be read the same backwards as forward). She has learned how to check for a given string whether it's a palindrome or not, but soon she grew tired of this problem, so she came up with a more interesting one and she needs your help to solve it:

You are given an array of strings which consist of only small letters of the alphabet. Your task is to find how many palindrome pairs are there in the array. A palindrome pair is a pair of strings such that the following condition holds: at least one permutation of the concatenation of the two strings is a palindrome. In other words, if you have two strings, let's say "aab" and "abcac", and you concatenate them into "aababcac", we have to check if there exists a permutation of this new string such that it is a palindrome (in this case there exists the permutation "aabccbaa").

Two pairs are considered different if the strings are located on different indices. The pair of strings with indices (i,j)(i,j) is considered the same as the pair (j,i)(j,i).

Input

The first line contains a positive integer NN (1≤N≤1000001≤N≤100000), representing the length of the input array.

Eacg of the next NN lines contains a string (consisting of lowercase English letters from 'a' to 'z') — an element of the input array.

The total number of characters in the input array will be less than 10000001000000.

Output

Output one number, representing how many palindrome pairs there are in the array.

Examples

input

Copy

3
aa
bb
cd

output

Copy

1

input

Copy

6
aab
abcac
dffe
ed
aa
aade

output

Copy

6

Note

The first example:

  1. aa ++ bb →→ abba.

The second example:

  1. aab ++ abcac == aababcac →→ aabccbaa
  2. aab ++ aa == aabaa
  3. abcac ++ aa == abcacaa →→ aacbcaa
  4. dffe ++ ed == dffeed →→ fdeedf
  5. dffe ++ aade == dffeaade →→ adfaafde
  6. ed ++ aade == edaade →→ aeddea

 

 

一、原题地址

点我传送

 

二、大致题意

样例解释的很清楚,就是找出n个串中组合起来能形成回文串的个数。

 

三、思路

串具体长成什么样子是无所谓的,只需要知道一个串里面各个字母的奇偶。

那么可以用一个长度为26的01串来记录一个给出的字符中字母的奇偶性。

用一个map保存之后,枚举一下就行了。

 

四、代码

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<map>
using namespace std;
typedef long long LL;

const int inf=0x3f3f3f3f;
int n;
char s[1000005];
int num[30];
map<int,LL>mp;
int main()
{
    scanf("%d",&n);
    for(int cnt=1;cnt<=n;cnt++)
    {
        scanf("%s",s);
        int len=strlen(s);
        memset(num,0,sizeof(num));
        for(int i=0;i<len;i++) num[s[i]-'a']++;
        int state=0;
        for(int i=0;i<26;i++)
        {
            if(num[i]&1)
            {
                state|=(1<<i);
            }
        }
        mp[state]++;
    }
    LL ans=0;
    map<int,LL>::iterator it;
    for(it=mp.begin();it!=mp.end();it++)
    {
        int state=it->first;
        int nu=it->second;
        int shu=0;
        ans+=mp[state]*(mp[state]-1)/2;
        for(int i=0;i<26;i++)
        {
            if((state>>i)&1)
            {
                shu++;
                int nx=state^(1<<i);
                ans+=mp[state]*mp[nx];
            }
        }
    }
    printf("%lld\n",ans);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值