Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], skipTags: ["script","noscript","style","textarea","code"], processEscapes: true }});

問題文

文字列 $S$ が与えられる。$S$ のすべてのアナグラムのうち、回文になっているものの個数を求めよ。

文字列 $X$ が $Y$ のアナグラムであるとは、$X$ が $Y$ と等しいか、$X$ の文字を並び替えたら $Y$ に等しくなることをいう。例えば文字列abcdに対して、abcdやcbdaなどはアナグラムであるが、abedやcabやabcddなどはアナグラムでない。

文字列 $X$ が回文であるとは、$X$ を逆から読んだものが $X$ 自身と等しくなることをいう。例えばabcやabは回文でなく、aやabccbaなどは回文である。

入力

入力は以下の形式に従う。

$S$

制約

$1 \leq |S| \leq 40$ ( $|S|$ は文字列 $S$ の長さ)

$S$ は小文字の英字のみを含む。

答は $2^{63}$ 未満であることが保証される。

出力

個数を1行に出力せよ。

Sample Input 1

ab

Output for the Sample Input 1

0

abのアナグラムはabとbaの二つがあるが、どちらも回文になっていない。

Sample Input 2

abba

Output for the Sample Input 2

2

abbaとbaabの二つの文字列が回文かつアナグラムになっている。

Solution in JAVA (judge verdict: Accepted)

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

	static Scanner sc = new Scanner(System.in);

	static long solve() {
		char[] s = sc.next().toCharArray();
		int[] count = new int[26];
		for (int i = 0; i < s.length; ++i) {
			++count[s[i] - 'a'];
		}
		int odd = 0;
		for (int i = 0; i < count.length; ++i) {
			if (count[i] % 2 != 0) ++odd;
		}
		if (s.length % 2 == 0) {
			if (odd != 0) return 0;

		} else {
			if (odd != 1) return 0;
		}
		for (int i = 0; i < count.length; ++i) {
			count[i] /= 2;
		}
		BigInteger[] fact = new BigInteger[s.length / 2 + 1];
		fact[0] = BigInteger.ONE;
		for (int i = 1; i < fact.length; ++i) {
			fact[i] = fact[i - 1].multiply(BigInteger.valueOf(i));
		}
		BigInteger ans = fact[s.length / 2];
		for (int i = 0; i < count.length; ++i) {
			ans = ans.divide(fact[count[i]]);
		}
		return ans.longValue();
	}

	public static void main(String[] args) {
		System.out.println(solve());
	}
}