AGC026 C - String Coloring

問題

長さ2Nの文字列Sを「赤色で塗った文字列を左から右に読んだもの と 青色で塗った文字列を右から左に読んだもの が同じになる」ように塗る方法は何通りあるか求める

解法

半分全列挙
前半N文字の塗り方を決め、赤/青で塗った文字列をx/yとすると、条件を満たすには後半N文字で赤/青で塗る文字列はそれぞれreverseしたy/xである必要がある
ex) 前半が abcd なら後半は dbcaでないといけない

実装

前半部分でx,yのpairを列挙してmapで数えて、後半部分でそれを使って↑のように答えを数える

ll n, res;
string s;
map<pair<string,string>, ll> a;
 
signed main() {
	cin >> n >> s;
	rep(i,1<<n) {
		string x, y;
		rep(j,n) (i>>j&1 ? x : y).push_back(s[j]);
		a[{x,y}]++;
	}
	rep(i,1<<n) {
		string x, y;
		rep(j,n) (i>>j&1 ? y : x).push_back(s[n+j]);
		reverse(all(x)), reverse(all(y));
		res += a[{x,y}];
	}
	cout << res << endl;
}