Problem:
Score : 600 points

Problem Statement

You are given a string S of length 2N consisting of lowercase English letters.

There are 2^{2N} ways to color each character in S red or blue. Among these ways, how many satisfy the following condition?

The string obtained by reading the characters painted red from left to right is equal to the string obtained by reading the characters painted blue from right to left.

Constraints

1 \leq N \leq 18

The length of S is 2N.

S consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

N
S

Output

Print the number of ways to paint the string that satisfy the condition.

Sample Input 1

4
cabaacba

Sample Output 1

4

There are four ways to paint the string, as follows:

cabaacba

cabaacba

cabaacba

cabaacba

Sample Input 2

11
mippiisssisssiipsspiim

Sample Output 2

504

Sample Input 3

4
abcdefgh

Sample Output 3

0

Sample Input 4

18
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Sample Output 4

9075135300

The answer may not be representable as a 32-bit integer.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>

#define FILE_NAME "atcoder.agc026_c"
#define SZ(x) ((int) x.size())
#define pb push_back
#define ppb pop_back
#define x first
#define y second
#define mkp make_pair
#define show(x) cout << (#x) << ": " << x << endl

using namespace std;
// using namespace __gnu_pbds;

using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pli = pair<ll, int>;
using pil = pair<int, ll>;
template<typename T> using Array = vector<T>;
template<typename T> using Matrix = Array<Array<T>>;
using Graph = Matrix<int>;

// template<typename T> using Set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template<typename T> bool relax(T& r, const T& x) {
    if (x < r) {
        r = x;
        return true;    
    }
    return false;
}

template<typename T> bool heavy(T& h, const T& x) {
    if (h < x) {
        h = x;
        return true;            
    }
    return false;
}

const int DX[8] = {-1, +1, +0, +0, +1, -1, +1, -1};
const int DY[8] = {+0, +0, -1, +1, +1, -1, -1, +1};

/************************************************************
* find_by_order(k) = iterator to (k)-th greatest element    *
* order_of_key(k) = counts number of strictly less elements *
*************************************************************/                                                           

signed main() {
#ifdef LOCAL
    freopen(FILE_NAME".in", "r", stdin);
    freopen(FILE_NAME".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    string s;
    cin >> s;
    map<string, map<string, int>> cnt;
    for (int mask = 0; mask < (1 << n); mask++) {
        string s0 = "", s1 = "";
        for (int i = 0; i < n; i++)
            if (mask & (1 << i))
                s0 += s[i];
            else
                s1 += s[i];
        reverse(s1.begin(), s1.end());
        cnt[s0][s1]++;                                        
    }
    ll ans = 0;
    for (int submask = 0; submask < (1 << n); submask++) {
        ll mask = ((ll) submask << n);
        string s2 = "", s3 = "";
        for (int i = n; i < 2 * n; i++)
            if (mask & (1ll << i))                    
                s2 += s[i];
            else
                s3 += s[i];
        reverse(s3.begin(), s3.end());
        ans += cnt[s3][s2];                    
    }
    cout << ans;
    return false;
}