hdu5651 xiaoxin juju needs help (多重集的全排列+逆元)

xiaoxin juju needs help

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

知识点:

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

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

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

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

题解:

字符串长度为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(T\leq 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
时间: 2024-10-29 06:11:41

hdu5651 xiaoxin juju needs help (多重集的全排列+逆元)的相关文章

HDU 5651 xiaoxin juju needs help(BestCoder Round #77 (div.1)1001)

传送门 xiaoxin juju needs help Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 861    Accepted Submission(s): 243 Problem Description As we all known, xiaoxin is a brilliant coder. He knew **palin

多重集的全排列

[多重集的全排列]

HDU 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!*

HDU 5651 xiaoxin juju needs help

组合数杨辉三角打表,这样避免了除法求逆元. #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> using namespace std; const long long MOD=1000000007; const int maxn=1000+10; long long c[maxn][maxn]; int tot[30]; c

hdu 5651 重复全排列+逆元

知识点: n个元素,其中a1,a2,····,an互不相同,进行全排列,可得n!个不同的排列. 若其中某一元素ai重复了ni次,全排列出来必有重复元素,其中真正不同的排列数应为 ,即其重复度为ni! 同理a1重复了n1次,a2重复了n2次,····,ak重复了nk次,n1+n2+····+nk=n. 对于这样的n个元素进行全排列,可得不同排列的个数实际上是  由于题目要求是对100000007取余 同余定理中对于同一个除数,两个数的乘积与它们余数的乘积同余.但这里有除法所以得用上逆元 逆元 定义

全排列生成算法

全排列的生成算法, next_permutation_1 可以用于生成多重集的全排列,next_permutation_2不能用于多重集 #include <cstdio> #include <cstring> #include <vector> using namespace std; bool next_permutation_1(vector<int>& vec){ int n = vec.size()-1; for(;n>0;n--){

BestCoder Round #77 (div.2)(hdu5650,hdu5651(逆元),hdu5652(二分),hdu5653(dp))

so easy 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5650 解题思路: 中文题目: 问题描述 已知一个包含 nn 个元素的正整数集合 SS,设 f(S)f(S) 为集合 SS 中所有元素的异或(XOR)的结果. 如:S = \{1, 2, 3\}S={1,2,3}, 则 f(S) = 0f(S)=0. 给出集合 SS,你需要计算 将所有 f(s)f(s) 进行异或后的值, 这里 s \subseteq Ss?S. 输入描述 多组测试数

csu1563: Lexicography以及找出多重集的第k个串的讲解

Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 162  Solved: 52 [Submit][Status][Web Board] Description An anagram of a string is any string that can be formed using the same letters as the original. (We consider the original string an anagram of its

HDU 5651 逆元

xiaoxin juju needs help Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 809    Accepted Submission(s): 231 Problem Description As we all known, xiaoxin is a brilliant coder. He knew **palindromi