51Nod 1453 抽彩球
题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
收藏
关注
一个袋子中有n个彩球,他们用k种不同的颜色染色。颜色被从1到k编号。同一种颜色的球看成是一样的。现在从袋中一个一个的拿出球来,直到拿完所有的球。对于所有颜色为i (1<=i<=k-1)的球,他的最后一个球总是在编号比他大的球拿完之前拿完,问这样情况有多少种。
样例解释:这个样例中有2个1号颜色的球,2个2号颜色的球,1个3号颜色的球。三种方案是:
1 2 1 2 3
1 1 2 2 3
2 1 1 2 3
Input
单组测试数据。
第一行给出一个整数k(1 ≤ k ≤ 1000),表示球的种类。
接下来k行,每行一个整数ci,表示第i种颜色的球有ci个(1 ≤ ci ≤ 1000)。
球的总数目不超过1000。
Output
输出总数对1,000,000,007的模即可。
Input示例
3
2
2
1
Output示例
3
正着放球有许多限制 我们很难求解
我们可以考虑反着放
题目要求 你想放最后一个种类为2的球 那么你种类为1的球一定已经全部放在这最后一个种类为2的球的前面位置 (看着样例理解)
对于第i个 球我们一定会在最后一个空位置放一个 然后其他的可以在前面的空位置随便放
就是 C(空位置数量,c[i]-1)
对于第i-1种球 我们要先在最后一个空位置放一个 其他再往前放
.
.
.
可以发现
这就是求一个组合数C(n,m) 由于 n,m 在10^6左右
我们可以用Lucas定理
Lucas定理 C(n,m)%p(p为素数) C(n,m)与C(a[n],b[n])*C(a[n-1],b[n-1])*C(a[n-2],b[-2])*....*C(a[0],b[0])模p同余 a,b 是n,m在p进制下的数 有的推公式: (C(n%p,m%p,p)*Lcs(n/p,m/p,p))%p; 关键是求 C(n%p,m%p,p) 递归会很慢 for的话会爆掉 这里用一个定理:a/b%p <--> a*x%p x为b在b%p下的逆元 再来一个定理:x=b^(p-2) x为b在%p下的逆元 p为素数 然后预处理一下阶乘就ok了
1 #include <cctype> 2 #include <cstdio> 3 4 typedef long long LL; 5 6 const int mod=1e9+7; 7 const int MAXN=1000010; 8 9 int n,sum; 10 11 int c[MAXN]; 12 13 LL fact[MAXN]; 14 15 inline void read(int&x) { 16 int f=1;register char c=getchar(); 17 for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar()); 18 for(;isdigit(c);x=x*10+c-48,c=getchar()); 19 x=x*f; 20 } 21 22 inline LL quick_pow(LL a,LL k) { 23 LL ret=1; 24 while(k) { 25 if(k&1) ret=(ret*a)%mod; 26 k>>=1; 27 a=(a*a)%mod; 28 } 29 return ret%mod; 30 } 31 32 inline LL C(int a,int b) { 33 return fact[a]*quick_pow(fact[b]*fact[a-b]%mod,mod-2)%mod; 34 } 35 36 inline void Factorial() { 37 fact[0]=1; 38 for(int i=1;i<=MAXN;++i) 39 fact[i]=(fact[i-1]*i)%mod; 40 } 41 42 int hh() { 43 Factorial(); 44 read(n); 45 for(int i=1;i<=n;++i) read(c[i]),sum+=c[i]; 46 LL ans=1; 47 for(int i=n;i;--i) { 48 ans=(ans*C(sum-1,c[i]-1))%mod; 49 sum-=c[i]; 50 } 51 printf("%lld\n",ans); 52 return 0; 53 } 54 55 int sb=hh(); 56 int main(int argc,char**argv) {;}
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现