回文
时间限制 :
- MS
空间限制 :
65536 KB
评测说明 : 时限1000ms
![](http://42.247.7.121/Content/Images/Site/icon_question.png)
问题描述:
给你一个由N个小写字母构成的字符串,请你将它改成“回文串”。你可以任意调整串中字符的位置,但不可以删掉其中的字符。问,最多能得到多少个不同的回文串?
结果可能很大,mod 1,000,000,007 后再输出!
例如给出字符串“aabb”
我们通过调整能得到两个回文串,分别是“abba”和”baab”
输入格式:
一行,一个字符串
输出格式:
一个整数,表示所求答案样例输入:
aabb
样例输出:
2
提示:
1<=n<=2000
首先分析满足构成回文串的条件
1.N为奇数:串中只有一个字母出现次数为奇数,其余全为偶数;
2.N为偶数:串中所有字母出现的次数都为偶数
2.N为偶数:串中所有字母出现的次数都为偶数
然后我们再分析在满足构成回文串的条件下计算方案的方法
事先统计出每个字母出现的次数,分别为cnt1,cnt2,......,cnt26
因为回文串左右对称,我们只需要讨论左边N/2个位置的情况即可。
令N=N/2, cnt1/=2 , cnt2/=2 ,......., cnt26/=2
令N=N/2, cnt1/=2 , cnt2/=2 ,......., cnt26/=2
对于字母'a',它可以从N个位置中选cnt1个位置出来放置
方案数为C[N][cnt1]
方案数为C[N][cnt1]
对于字母'b',它可以从N-cnt1个位置中选cnt2个位置出来放置,方案数为C[N-cnt1][cnt2]
以此类推,总方案数即为C的所有乘积对于1000000007取模
但是为了防止中间结果溢出,我们应该注意用乘法逆元求解
根据组合数公式:
化简得:((N!)/ (cnt1! * cnt2! *......*cnt26!) ) mod 1000000007
令T=cnt1! * cnt2! *......*cnt26! 根据(T * T-1) ≡ 1 (mod 100000007)
通过扩欧可求得T的乘法逆元T-1
((N!)/ (cnt1! * cnt2! *......*cnt26!) ) mod 1000000007
=(N! * T-1)mod 100000007
=((N! mod 100000007)*(T-1 mod 100000007)) mod 100000007
通过扩欧可求得T的乘法逆元T-1
((N!)/ (cnt1! * cnt2! *......*cnt26!) ) mod 1000000007
=(N! * T-1)mod 100000007
=((N! mod 100000007)*(T-1 mod 100000007)) mod 100000007
#include<iostream>
#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;
const int mod=1000000007;
char s[2005];
LL cnt[30],fr[2005],r[2005]; //r数组记录的是乘法逆元
LL adv(LL a,LL b,LL &x,LL &y){
LL x0,y0,r;
if(b==0){x=1;y=0;return a;}
r=adv(b,a%b,x0,y0);
x=y0;y=x0-a/b*y0;
return r;
} //拓展欧几里德
int main(){
LL i,j,n,odd=0,t=0,x,y;
scanf("%s",s+1);
n=strlen(s+1);
for(i=1;i<=n;i++)
cnt[s[i]-'a'+1]++;
for(i=1;i<=26;i++){
if(cnt[i]&1)odd++;
cnt[i] >>=1;
t+=cnt[i];
}
if(odd>1){puts("0");return 0;} //判断无法凑成回文的情况
fr[0]=1;
for(i=1;i<=t;i++)fr[i]=fr[i-1]*i%mod;
LL ans=fr[t];
for(i=1;i<=t;i++){
LL gcd=adv(fr[i],mod,x,y);
if(gcd==1)r[i]=(x+mod)%mod;
else r[i]=-1; //若无乘法逆元,返回-1
}
for(i=1;i<=26;i++)
if(cnt[i])ans=ans*r[cnt[i]]%mod; 求最终答案
cout<<ans%mod;
}
时间限制 : - MS 空间限制 : 65536 KB
评测说明 : 时限1000ms
![](http://42.247.7.121/Content/Images/Site/icon_question.png)