过不了样例2,思路可能有误,求HACK
查看原帖
过不了样例2,思路可能有误,求HACK
349824
WsW_花逝爆零人楼主2025/1/18 11:44

大致思路是:
如果有两个以上的字母是奇数个,那肯定都非回文,输出 n!n!

然后求回文串,只考虑半边的字符串是啥形状,另外半边肯定是相同形状,产生 t=n2t=\lfloor \frac{n}{2} \rfloor 的贡献。
接着考虑每个字母,在已知字符串形状的情况下,任意两个相同字母换一下位置都是新的回文串,所以每个字母会产生 cntchar!cnt_{char}! 的贡献。
然后把所有贡献乘起来,用 n!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;
}
2025/1/18 11:44
加载中...