【HPU 1011 QAQ的序列组合】

1011: QAQ的序列组合
时间限制: 1 Sec 内存限制: 128 MB
提交: 112 解决: 17
[提交][状态][讨论版]
题目描述
QAQ有1−N
共N个不同的整数,已知第i个整数有a[i]
个。
现在QAQ想知道一共有多少种不同的组合方案。
输入
第一行输入一个整数T
,代表有T组测试数据。
每组数据占两行,第一行输入一个整数N,代表N个不同的整数。
接下来输入N个整数a[]。

注:1<=T<=30,1<=N<=10000,0<=a[]<=100

输出

对每组测试数据,输出一个整数代表不同的组合方案。

由于结果可能会很大,请对(109+7)

取余。
如果所有整数的个数之和为0
,我们认为不存在合法的方案。
样例输入

2
3
1 1 1
3
1 1 2

样例输出

6
12

提示

对于第二组测试数据,有1 2 3 3共4个整数。
不同组合的方案有:
(1 2 3 3)、(1 3 2 3)、(1 3 3 2)、(2 1 3 3)、(2 3 1 3)、(2 3 3 1)、
(3 1 2 3)、(3 2 1 3)、(3 1 3 2)、(3 2 3 1)、(3 3 1 2)、(3 3 2 1)、
共12种。

记pa[i]是i元素出现的次数。
然后枚举每一个状态,共有(1<<10)−1共1023种状态。
对于状态S而言,若出现N个元素,那么它们的组合方案就是
cnt=(2^(pa[i]−1))∗(2^(pa[i+1]−1))∗…∗(2^(pa[N]−1))。
状态S的贡献就是出现的不同元素和sum 乘上 组合方案cnt。
我们累加贡献即可。
如果爆int,要这样写1 LL << x。
时间复杂度O(T∗1023∗10)。

AC代码 :

#include<cstdio>
const long long mod = 1e9 + 7;
int pa[10010];
long long jc[1000011];
long long KSM(long long x,long long y)
{
    long long cut = x % mod;
    long long sum = 1;
    while(y){
        if(y & 1)
            sum = sum * cut % mod;
        cut = cut * cut % mod;
        y /= 2;
    }
    return sum;
}
int main()
{
    int T,N,i,a;
    long long ans;
    jc[0] = 1;
    for(i = 1 ; i <= 1000011 ; i++)
        jc[i] = jc[i - 1] * i % mod;
    scanf("%d",&T);
    while(T--){
            ans = 0;
        scanf("%d",&N);
        for(i = 1 ; i <= N ; i++){
            scanf("%d",&pa[i]);
            ans += pa[i];
        }
        if(ans == 0)
            printf("0\n");
        else{
            ans = jc[ans];
            for(i = 1 ; i <= N ; i++){
                a = pa[i];
                if(a)
                ans = ans * KSM(jc[a] , mod - 2) % mod;
            }
        printf("%lld\n",ans);
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值