//バブルソートは任意の順列をソートできる→任意の順列を作ることができると言っても良い //Sの順列の総数 - 1が答えとなる //文字xの個数をa[x]とすれば、|S|!/Πa[x]! - 1 (mod 573) ('A' <= x <= 'Z')が答えになるが、 //573が素数ではないので、これを直接求めることはできない。 // //上の式は、「n個の中からa[x]個を選び文字xにする」を繰り返して出来る順列の総数ともいえるので、 //C(n, a['A']) * C(n - a['A'], a['B']) * C(n - a['A'] - a['B'], a['C']) * … - 1と同じ結果になる。 //これは逐次modを取りながら計算できるので、これを計算する。コンビネーションは前処理で求めておく //O(n^2) (nはSの長さ) #include #include using namespace std; string s; int comb[1001][1001]; int cnt[26]; int main(){ int i, j, n; cin >> s; n = s.length(); comb[0][0] = 1; for( i = 1; i <= n; i++ ){ for( j = 0; j <= n; j++ ){ comb[i][j] = comb[i-1][j] + ((j > 0) ? comb[i-1][j-1] : 0); comb[i][j] %= 573; } } for( i = 0; i < n; i++ ){ cnt[s[i] - 'A']++; } int diff = n; int ans = 1; for( i = 0; i < 26; i++ ){ ans *= comb[diff][cnt[i]]; ans %= 573; diff -= cnt[i]; } ans = (ans + 572) % 573; //法573の元で-1する cout << ans << endl; return 0; }