HDU 5651(排列组合,逆元)

来源:互联网 发布:保定seo外包 编辑:程序博客网 时间:2024/04/28 08:42

hdu 5615

思路:
len = 1, ans = 1;
统计每个字母出现个数,cnt_(奇数个个数的字母)>1; ans = 0;

排列序列左端;
设 (a,b,c...z)=(n1,n2,n3...n26), n=26i=1ni;
ans=n!n1!n2!...n26!(mod(1e9+7))=n!
根据ababc2(modc) ,c为素数;
ans=(n!26i=1(nimod2(mod1e9+7)))(mod1e9+7)

#include <iostream>#include <cstring>#include <algorithm>#include <cstdlib>#include <cstdio>#define MOD 1000000007#define LL long longusing namespace std;LL fn[505];int a[30];void init(){    fn[1] = 1;    for (int i = 2; i <= 500; i++)    {        fn[i] = (fn[i - 1] * i) % MOD;    }}LL quick_Mod(LL m, LL n, LL k)    //(n ^ m) % k;  ((n % k) ^ m) % k == (n ^ m) % k;{    LL ans = 1;    while (n)    {        if (n & 1)        {            ans = (ans * m) % k;        }        n = n >> 1;        m = (m * m) % k;     }    return ans;}int main(){    int T;    scanf("%d", &T);    init();    char ss[1005];    while (T--)    {        scanf("%s", ss);        // printf("%s\n", ss);        memset(a, 0, sizeof(a));        int len = strlen(ss);        if (len == 1)        {            printf("1\n");            continue;        }        // cout << len << endl;        for (int i = 0; i < len; i++)        {            a[ss[i] - 'a']++;        }        bool flag = 0;        int cnt = 0;        for (int i = 0; i < 26; i++)        {            if (a[i] & 1)            {                a[i]--;                cnt++;            }            if (cnt > 1)            {                flag = 1;                printf("0\n");                break;            }        }        if (flag == 1)        {            continue;        }        LL ans = 1;        LL tmp = fn[len/2];        for (int i = 0; i < 26; i++)        {            if (a[i] != 0)            {                // cout << i << ' ' <<  a[i] << endl;                 ans = (ans * quick_Mod(fn[a[i] / 2], MOD - 2, MOD)) % MOD;            }        }        // cout << tmp << ' ' << ans << endl;        ans = (ans * tmp) % MOD;        printf("%lld\n", ans);    }}
0 0
原创粉丝点击