2020牛客国庆集训派对day5 B.Hyperdrome
题目描述
Hypergnome planet is famous for its Great Universal Games between gnomes — the Games between gnomes from each part of the galaxy in various disciplines.
The most popular discipline in the Games is the Hyperdrome discipline. The rules are the follows: one string of length n is given to all gnomes. The gnomes shall find, as fast as they can, the total number of Hyperdrome substrings — such strings that characters inside the string can be rearranged to get a palindrome.
Substring is defined as a sequence of characters from position i to position j inclusive, where 1 ≤ i ≤ j ≤ n. Substrings with different pairs of positions (i, j) are considered different regardless of their contents.
Palindrome is defined as a string x1x2…xl, where xi = xl−i+1 for all 1 ≤ i ≤ l.
Judges choose a string and your task is to help them find the answer.
The gnome alphabet consists of lowercase and uppercase English letters — ‘a’–‘z’ and ‘A’–‘Z’ where letters in different case are considered to be different letters.
输入描述:
The first line of the input file contains a single integer n (1 ≤ n ≤ 3 · 105).
The second line of the input file contains the string for Hyperdrome discipline — n lowercase or uppercase English letters.
输出描述:
Output the answer for the Hyperdrome discipline — the number of Hyperdrome substrings in the input string.
示例1
输入
3
aaa
输出
6
示例2
输入
7
abadaba
输出
12
示例3
输入
3
aAA
输出
5
思维题~
题意比较简单,就是求字符串有多少子串重排列可以得到回文串~
巧解就是转化为位运算,把
a
−
Z
a-Z
a−Z 一共 52 个字符看成 52 个二进制位,用
m
a
p
map
map 记录所有状态,对当前状态,求出所有可能状态,如果存在就加到答案里即可,AC代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+5;
char s[N];
int n;
ll ans=0,sum=0,tmp;
int main(){
scanf("%d%s",&n,s);
unordered_map<ll,ll>m;
m[0]=1;
for(int i=0;i<n;i++){
if(islower(s[i])) tmp=s[i]-'a';
else tmp=s[i]-'A'+26;
sum^=(1LL<<tmp);
for(ll j=0;j<52;j++){
if(m.count(sum^(1LL<<j))) ans+=m[sum^(1LL<<j)];
}
if(m.count(sum)) ans+=m[sum];
else m[sum]=0;
m[sum]++;
}
printf("%lld",ans);
return 0;
}