大致思路是:
如果有两个以上的字母是奇数个,那肯定都非回文,输出 n!。
然后求回文串,只考虑半边的字符串是啥形状,另外半边肯定是相同形状,产生 t=⌊2n⌋ 的贡献。
接着考虑每个字母,在已知字符串形状的情况下,任意两个相同字母换一下位置都是新的回文串,所以每个字母会产生 cntchar! 的贡献。
然后把所有贡献乘起来,用 n! 减去。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long ull;
const int p=1e9+7;
int n;
string s;
int cnt[31];
int fac[2003]={1};
ll ans;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>s;
for(int i=0;i<n;i++){
fac[i+1]=fac[i]*(i+1)%p;
cnt[s[i]-'a']++;
}
ans=fac[n>>1]%p;
bool f=0;
for(int i=0;i<26;i++){
if(cnt[i]&1){
if(f){
cout<<fac[n];
return 0;
}
f=1;
}
if(!cnt[i])continue;
(ans*=fac[cnt[i]])%=p;
}
cout<<(fac[n]-ans+p)%p;
return 0;
}