描述:
acm 有1 - N 共 N 个不同的整数,已知第 i 个整数有 a [ i ] 个。
现在 acm 想知道一共有多少种不同的组合方案。
输入:
第一行输入一个整数 T,代表有 T 组测试数据。
每组数据占两行,第一行输入一个整数 N,代表 N 个不同的整数。
接下来输入 N 个整数 a [ ] 。
注:1 <= T <= 30,1 <= N <= 10000,0 <= a[] <= 100。
输出:
对每组测试数据,输出一个整数代表不同的组合方案。
由于结果可能会很大,请对 (1e9 + 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)、
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
const LL MOD=1e9+7;
const int MAXN=1e6+10;
int n,num[MAXN];
LL fac[MAXN];
LL qpow(LL a,LL b)
{
LL base=a,ans=1;
while(b)
{
if(b&1)
{
ans=ans*base%MOD;
}
base=base*base%MOD;
b>>=1;
}
return ans;
}
LL C(int a,int b)
{
return fac[a]*qpow(fac[a-b],MOD-2)%MOD*qpow(fac[b],MOD-2)%MOD;
}
int main()
{
fac[0]=1;
for(int i=1;i<=MAXN-10;i++)
fac[i]=fac[i-1]*i%MOD;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int sum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&num[i]);
sum+=num[i];
}
if(sum==0)
{
puts("0");
continue;
}
LL ans=1;
for(int i=0;i<n;i++)
{
ans=ans*C(sum,num[i])%MOD;
sum-=num[i];
}
printf("%lld\n",ans);
}
return 0;
}