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: Time Limit Exceeded)


//#include "pch.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <utility>
#include <queue>
#include <algorithm>
#include <functional>
#include <string>

#define ll long long
#define fri(n) for(i=0;i<(n);i++)
#define frj(n) for(j=0;j<(n);i++)
#define min(p,q) ((p)<(q)?(p):(q))
#define max(p,q) ((p)>(q)?(p):(q))
#define swap(p,q) r=(p);(p)=(q);(q)=r
#define INF 1000000000000//10^12
#define INFINT 2000000001//2*10^9+1
#define ALL(a) (a).begin(),(a).end()

using namespace std;


struct kouzou_t{
	string str;	
	int idnum;

	bool operator<(const kouzou_t& another) const {
		int x=str.compare(another.str);
		if(x>=0) return 1;
		return 0;
	}
};


int main(void)
{
	//変数の宣言
	int n;
	char s[40];
//	string str;
	struct kouzou_t memo;
	vector<kouzou_t> dp;
	struct kouzou_t kouzou;
	int ng,ok;

	//よく使う変数
	int i,j,k,l;
	int flag=0;
	ll int ans=0;
	int count=0;
	int temp,temp1,temp2;
	int max,min;
	int len;
	int sum=0;



	//データの読み込み


	scanf("%d",&n);
//	scanf_s("%d",&n);

	scanf("%s",&s);
//	scanf_s("%s",&s,40);

//	for(i=1;i<=n;i++){
//		scanf("%lld %lld %d",&x[i],&y[i],&r[i]);
//		scanf_s("%lld %lld %d",&x[i],&y[i],&r[i]);
//	}
	
	//	printf("nは%dです\n", n);
	//	printf("データの読み込み終了\n");
	//実際の処理

	for(i=0;i<(1<<n);i++){
		temp=0;
		for(j=0;j<n;j++){
			if((i&(1<<j))==0){
				kouzou.str.push_back(s[j]);
				temp++;
			}
		}
		kouzou.str.push_back(',');
		for(j=0;j<n;j++){
			if((i&(1<<j))!=0){
				kouzou.str.push_back(s[j]);
			}
		}

//		printf("%s\n",kouzou.str.c_str());

		kouzou.idnum=1;
		dp.push_back(kouzou);
		kouzou.str.erase(kouzou.str.begin(),kouzou.str.end());
		
	}

	
/*	for(auto itr=dp.begin();itr!=dp.end();++itr){
		memo=*itr;
		printf("%s\n",memo.str.c_str());
	}
*/
	sort(dp.begin(),dp.end());

	for(i=0;i<(1<<n);i++){
		dp[i].idnum=i;
	}

/*	for(auto itr=dp.begin();itr!=dp.end();++itr){
		memo=*itr;
		printf("%s\n",memo.str.c_str());
	}
*/




	for(i=0;i<(1<<n);i++){
		for(j=0;j<n;j++){
			if((i&(1<<j))==0){
				kouzou.str.push_back(s[2*n-1-j]);
			}
		}
		kouzou.str.push_back(',');
		for(j=0;j<n;j++){
			if((i&(1<<j))!=0){
				kouzou.str.push_back(s[2*n-1-j]);
			}
		}

		ng=-1;
		ok=(1<<n);
		while(ok-ng>1){
//			printf("%d\n",dp[(ok+ng)/2].str.compare(kouzou.str));
			if(dp[(ok+ng)/2].str.compare(kouzou.str)>0){
				ng=(ok+ng)/2;
			}else{
				ok=(ok+ng)/2;
			}
		}
		ans=ans-ok;
		
		ng=-1;
		ok=(1<<n);
		while(ok-ng>1){
			if(dp[(ok+ng)/2].str.compare(kouzou.str)>=0){
				ng=(ok+ng)/2;
			}else{
				ok=(ok+ng)/2;
			}
		}
		ans=ans+ok;
		
		kouzou.str.erase(kouzou.str.begin(),kouzou.str.end());
	}


	//	printf("計算部分終了\n");

	//出力

	printf("%lld",ans);

	//	printf("結果の出力終了\n");


	return 0;
}