HDU 5651xiaoxin juju needs help 带模除法逆元+有重复元素的全排列值

来源:互联网 发布:钓鱼源码 编辑:程序博客网 时间:2024/06/11 00:35
点击打开链接xiaoxin巨从小就喜欢字符串,六年级的时候他就知道了什么是回文串。这时,xiaoxin巨说到:如果一个字符串 SSS 是回文串,那么该字符串从前往后看和从后往前看是一样一样的。六年级的暑假,xiaoxin很快就做完了暑假作业,然后到腾讯做起了实习生。这日,leader给了xiaoxin一个字符串,请xiaoxin帮忙写一个函数来生成所有可能的回文串,可以任意改变字符串的顺序但是不可以扔掉某个字符。并且leader告诉xiaoxin,每生成一个不一样的回文串就可以得到一颗西瓜糖。请你帮忙计算xiaoxin的leader最多需要买多少颗西瓜糖呢?
#include <iostream>#include <cstring>#include <cmath>#include<cstdio>#include<stack>#include <queue>#include <algorithm>#include <set>#include <map>#define LL __int64using namespace std;char s[1010];LL A[30];LL B[1010];LL J[1210]={1,1};const LL MOD=1e9+7;LL solve(LL x)       ///求带模除法逆元{    LL n=MOD-2;    LL ans=1;    while(n)    {        if(n&1)        {            (ans*=x)%=MOD;        }        (x*=x)%=MOD;        n>>=1;    }    return ans;}int main()  ///利用白书 104页 有重复元素的全排列公式             ///n1!*n2!*n3!*...*nk!*x=n!    x即为有重复元素的全排列值{    int t;    for(LL i=2;i<1011;i++)    {        (J[i]=J[i-1]*i)%=MOD;    }  scanf("%d",&t);  LL cnt;  while(t--)  {      memset(A,0,sizeof(A));      scanf("%s",s);      int tmp=0;      int len=strlen(s);      for(int i=0;s[i];i++)      {          A[s[i]-'a']++;      }      if(len==1)      {          printf("1\n");          continue;      }      cnt=0;      for(int i=0;i<26;i++)      {           if(A[i]%2)            tmp++;      }      for(int i=0;i<26;i++)        cnt+=A[i]/2;      if(tmp>1)      {          printf("0\n");          continue;      }      LL ans=J[cnt];      for(LL i=0;i<26;i++)      {          (ans*=(solve(J[A[i]/2])))%=MOD;      }      printf("%I64d\n",ans);  }    return 0;}

0 0
原创粉丝点击