51Nod 1453 抽彩球

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) {;}

代码


 
时间: 2024-08-07 08:19:07

51Nod 1453 抽彩球的相关文章

[51nod 1850] 抽卡大赛

问题描述 51Nod为了活跃比赛前的气氛,组织了场抽卡比赛.这场比赛共 n 个人参加,主办方根据非欧血统鉴定器,得到了一些数据.每个人抽卡有 Mi 种可能,得到的卡能力值为 Aij 代价为 Gij 的可能性为 Pij ,所谓代价指的是玩家需要将一轮比赛后所得的点头盾的 Gij% 交给主办方.每轮比赛每个人都随机抽取卡片,待全部人抽取完毕后进行排名(按照A从大到小排),排在第 i 位的人有 Vi 的点头盾收入.现在主办方想知道一轮比赛后每个人的期望收入. 输入格式 第一行一个正整数 n 接下来 n

51nod 1380 夹克老爷的逢三抽一 堆 脑洞题

51nod 1380 夹克老爷的逢三抽一堆 脑洞题 题意 n个人围成一圈 然后每次可以选一个人,得到他的分数,然后他与他相邻的两个人出圈 总共选 n/3次, 保证n是3的倍数 题解 这道怎么说呢,应该比较巧妙吧,你开一个优先队列,大根堆,每次选择优先队列中最大的数,然后把他左右两个数删掉,比如 A B C 删掉 B ,那么就把 A+C-B 加入优先队列中,这其实就是相当于提供了一个后悔的机会,就像网络流中的反向边,如果在选中这个点的话,就相当于 B+(A+C-B) 然后就相当于 B 这个点 不选

51Nod 1380 夹克老爷的逢三抽一

Description 一开始有一个环,可以选择删除一个元素获得他的权值,同时删除与它相邻的两个元素,其他元素重新形成环,问能获得的最大价值. Sol 堆+贪心. 一开始从堆中加入所有元素,然后取出一个元素之后,加入他两边的元素之和-该位置的权值,并把左右两点删除. 一直到取出 \(\frac {n} {3}\) 个元素即可,左右元素可以用链表维护. 这样取出一个元素了以后可以进行反悔的操作,获得另外两个权值. xyx大爷说只要不相邻那么元素个数使得他必然有一种合法的删除方案. Code #in

51nod 1378 夹克老爷的愤怒(树形DP+贪心)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1378 大致题意: 一棵1e5节点的树,安放某些位置,一个位置可以控制距他的距离不超过K的所有节点, 输入树和K,求控制全图(所有节点)需要安放最少的个数 思路: 假如是线性结构,一定是从边界开始每距离2k安放一个,然后最后正好或者再放置一个,这个贪心思路所有人都会. 当是树形结构时,仍然用那个贪心,显然安放的位置越靠近根节点控制的其他节点数越多,所以这里必须从

51nod 1201 整数划分(dp)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1201 题解:显然是一道dp,不妨设dp[i][j]表示数字i分成j个一共有几种分法. 那么转移方程式为: dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] 表示将i - 1划分为j个数,然后j个数都+1 还是不重复,将i - 1划分为j - 1个数,然后j - 1个数都+1,再加上1这个数. 然后就是j的范围要知道1+2+

51nod 1138 连续整数的和(数学)

题目描述: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1138 给出一个正整数N,将N写为若干个连续数字和的形式(长度 >= 2).例如N = 15,可以写为1 + 2 + 3 + 4 + 5,也可以写为4 + 5 + 6,或7 + 8.如果不能写为若干个连续整数的和,则输出No Solution. Input 输入1个数N(3 <= N <= 10^9). OutPut 输出连续整数中的第1个数,如果有多

51nod 1463 找朋友(线段树+离线处理)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序,因为k一共最多只有10个,所有在该区间内的B数组,每次枚举K值,通过这样的方式来得到另外一个B值.但是这样得到的B值它在B数组中的位置必须在当前数的左边.如下图:(j为当前数在B数组中的位置,pos为计算得到的另一个B值在数组中的位置) 这两个数的和记录在pos中,这里pos的位置必须在j的左边,假

51nod 1437

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1437 1437 迈克步 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 有n只熊.他们站成一排队伍,从左到右依次1到n编号.第i只熊的高度是ai. 一组熊指的队伍中连续的一个子段.组的大小就是熊的数目.而组的力量就是这一组熊中最小的高度. 迈克想知道对于所有的组大小为x(1 ≤ x ≤ n

51nod 1272 思维/线段树

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1272 1272 最大距离 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 给出一个长度为N的整数数组A,对于每一个数组元素,如果他后面存在大于等于该元素的数,则这两个数可以组成一对.每个元素和自己也可以组成一对.例如:{5, 3, 6, 3, 4, 2},可以组成11对,如下(数字为下标):