zoukankan      html  css  js  c++  java
  • hdu5651 xiaoxin juju needs help (多重集的全排列+逆元)

    xiaoxin juju needs help

    题意:给你一个字符串,求打乱字符后,有多少种回文串。                      (题于文末)

    知识点:

        n个元素,其中a1,a2,····,an互不相同,进行全排列,可得n!个不同的排列。

        若其中某一元素ai重复了ni次,全排列出来必有重复元素,其中真正不同的排列数应为 clip_image002[4],即其重复度为ni!

        同理a1重复了n1次,a2重复了n2次,····,ak重复了nk次,n1+n2+····+nk=n。

        对于这样的n个元素进行全排列,可得不同排列的个数实际上是 clip_image001

       

    题解:

    字符串长度为len,若每个元素的重复次数ni为奇数的个数count>1,则无法形成回文串。

    当能构成回文串时,我们只需考虑这个回文串左半部分的情况,所以这个问题也就变成了求一半字符串的有重复的全排列。

    因为涉及到除法取模的问题,所以用到逆元。

    逆元可以用扩展欧几里得,或费马小定理。/*6.逆元*/

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    const LL MOD=1e9+7;
    int cnt[260];
    char ch[1005];
    
    LL jiecheng(int n)
    {
        if(n==0)
            return 1;
        LL ans=1;
        for(int i=1;i<=n;i++)
            ans=ans*i%MOD;
        return ans;
    }
    
    LL x,y;
    LL gcd(LL a,LL b)
    {
        LL t,d;
        if(b==0)
        {
             x=1,y=0;
             return a;
        }
         d=gcd(b,a%b);
         t=x, x=y, y=t-(a/b)*y;
         return d;
     }
    
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            memset(cnt,0,sizeof(cnt));
            scanf("%s",ch);
            int len=strlen(ch);
            for(int i=0;i<len;i++)
            {
                cnt[ch[i]-' ']++;
            }
            int count=0;
            for(int i=0;i<260;i++)
            {
                if(cnt[i]&1)
                    count++;
                cnt[i]/=2;
            }
            if(count>1)
            {
                cout<<0<<endl;
                continue;
            }
            LL ans=jiecheng(len/2)%MOD;
            for(int i=0;i<260;i++)
            {
                if(cnt[i]>0)
                {
                    gcd(jiecheng(cnt[i]),MOD);
                    if(x<0)
                        x+=MOD;
                    ans=ans*x%MOD;
                }
            }
            cout<<ans<<endl;
        }
    }

    xiaoxin juju needs help

    Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

    Submit Status

    Description

    As we all known, xiaoxin is a brilliant coder. He knew **palindromic** strings when he was only a six grade student at elementry school.
    This summer he was working at Tencent as an intern. One day his leader came to ask xiaoxin for help. His leader gave him a string and he wanted xiaoxin to generate palindromic strings for him. Once xiaoxin generates a different palindromic string, his leader will give him a watermelon candy. The problem is how many candies xiaoxin's leader needs to buy?

    Input

    This problem has multi test cases. First line contains a single integer $T(Tleq 20)$ which represents the number of test cases.
    For each test case, there is a single line containing a string $S(1 leq length(S) leq 1,000)$.

    Output

    For each test case, print an integer which is the number of watermelon candies xiaoxin's leader needs to buy after mod $1,000,000,007$.

    Sample Input

    3 aa aabb a

    Sample Output

    1 2 1

  • 相关阅读:
    SharePoint 2013 图文开发系列之自定义字段
    SharePoint 2013 图文开发系列之Visual Studio 创建母版页
    SharePoint 2013 图文开发系列之代码定义列表
    SharePoint 2013 图文开发系列之计时器任务
    SharePoint 2013 图文开发系列之应用程序页
    SharePoint 2013 图文开发系列之事件接收器
    SharePoint 2013 图文开发系列之可视化WebPart
    SharePoint 2013 图文开发系列之WebPart
    SharePoint 2013 对二进制大型对象(BLOB)进行爬网
    SharePoint 2013 状态机工作流之日常报销示例
  • 原文地址:https://www.cnblogs.com/shentr/p/5349489.html
Copyright © 2011-2022 走看看