hdu5651 xiaoxin juju needs help(逆元)

 

xiaoxin juju needs help

 
 Accepts: 150
 
 Submissions: 966
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
xiaoxin巨从小就喜欢字符串,六年级的时候他就知道了什么是回文串。这时,xiaoxin巨说到:如果一个字符串 SS 是回文串,那么该字符串从前往后看和从后往前看是一样一样的。

六年级的暑假,xiaoxin很快就做完了暑假作业,然后到腾讯做起了实习生。这日,leader给了xiaoxin一个字符串,请xiaoxin帮忙写一个函数来生成所有可能的回文串,可以任意改变字符串的顺序但是不可以扔掉某个字符。并且leader告诉xiaoxin,每生成一个不一样的回文串就可以得到一颗西瓜糖。

请你帮忙计算xiaoxin的leader最多需要买多少颗西瓜糖呢?
输入描述
多组测试数据。第一行包含一个整数 T(T\leq 20)T(T20) 表示组数。每组测试数据给出一个只包含小写字母的字符串 S(1\leq length(S)\leq 1,000)S(1length(S)1,000)
输出描述
对于每组测试数据,输出一个数, 表示leader需要买的西瓜糖的个数,结果对 1,000,000,0071,000,000,007 取模。
输入样例
3
aa
aabb
a
输出样例
1
2
1

 

/*
5651  xiaoxin juju needs help(逆元)

给你n个字母,求可以组成的回文串的个数
1.n为奇数,有一个字母的个数为奇数
2.n为偶数,字母个数全为偶数

然后将字母的个数num[i]/2,得出在对称轴左边的个项字母的个数
假设左边有len个字母,如果每个字母都不同则有len!中可能
然后除去所有重复的可能num[i]!即可
因为除法取模 (len!/num[i]!)%mod
a^(p-1) = 1(mod p)p为素数    于是 a*a^(p-2) = 1(mod p)所以a^(p-2)替代1/a.
所以上面的公式  ->  len!*(num[i]!)^(p-2)%mod

hhh-2016-03-26 21:45:56	
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <functional>
using namespace std;
#define lson  (i<<1)
#define rson  ((i<<1)|1)
typedef long long ll;
const int maxn = 20050;
const int mod = 1e9+7;
int a[maxn];

char Ma[maxn];
int Mp[maxn];
int num[26];

ll pow_mod(ll a,ll n)
{
    ll t = 1;
    while(n)
    {
        if(n & 1) t = t*a%mod;
        a = a*a%mod;
        n >>= 1;
    }
    return t;
}

ll cal(int t)
{
    ll ans = 1;
    for(int i =1;i <= num[t];i++)
    {
        ans = ans*i%mod;
    }
    return pow_mod(ans%mod,mod-2);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",Ma);
        int sum = 0;
        int len = strlen(Ma);
        memset(num,0,sizeof(num));
        for(int i = 0; i < len; i++)
        {
            Mp[i] = Ma[i]-'a';
            if(num[Mp[i]] == 0)
                sum ++;
            num[Mp[i]]++;
        }
        int flag = 0;
        int t;
        for(int i = 0; i < 26; i++)
        {
            if(num[i]%2)
            {
                flag ++;
                t = num[i];
            }
        }
        if((len%2 && !flag) || (len%2==0 && flag) || (flag > 2))
            printf("0\n");
        else if(len == 1)
            printf("1\n");
        else
        {
            ll ans = 1;
            for(int i =1;i <= len/2;i++)
                ans = ans*i%mod;
            for(int i = 0;i < 26;i++)
            {
                if(num[i])
                {
                    num[i] /= 2;
                    ans = ans*cal(i)%mod;
                }
            }
            printf("%I64d\n",ans);
        }

    }
    return 0;
}

  


 


 

posted @ 2016-03-26 21:59  Przz  阅读(153)  评论(0编辑  收藏  举报