1. 程式人生 > >hdu 5651 組合數學+費馬小定理求逆元

hdu 5651 組合數學+費馬小定理求逆元

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1009
typedef long long ll;
char s[M];
int num[26];
const int mod = 1000000007;
ll qpow(ll x,ll n,ll mod)
{
    ll ans = 1;
    while(n)
    {
        if(n & 1) ans = ans * x % mod;
        x = x * x % mod;
        n >>= 1
; } return ans; } ll C(ll a,ll b) { ll s1 = 1, s2 = 1; for(int i = b - a + 1;i <= b;i++) s1 = s1*i%mod; for(int i = 1;i <= a;i++) s2 = s2*i%mod; ll inv = qpow(s2,mod-2,mod); return s1*inv%mod; //return (s1%(s2*mod))/s2; } int main() { ios::sync_with_stdio(false
); int T; cin >> T; while(T--) { cin >> s; memset(num,0,sizeof(num)); int len = strlen(s); for(int i = 0;i < len;i++) num[s[i] - 'a']++; int sum = 0; for(int i = 0;i < 26;i++) { if(num[i]&1) sum++; } if
(sum > 1) { cout << 0 << endl; continue; } ll ans = 1; sum = len/2; //只看左半邊 for(int i = 0;i < 26;i++) { if(!num[i]) continue; if(num[i] & 1) num[i]--; ans = ans*C(num[i]/2,sum)%mod; sum -= num[i]/2; //已經放過的位置要減掉 } cout << ans << endl; } return 0; }