礼物

来源:互联网 发布:个体户记账软件 编辑:程序博客网 时间:2024/06/11 01:03

礼物

节日到了,JIH决定给他的m个朋友们送礼物。他一共卖了n件礼物,不同的人对JIH来说重要性不同,对于第i个人,JIH会送wi件礼物给她。JIH想知道有多少种方法把礼物送出去,方案数mod p。

Input
第一行一个整数p
第二行两个整数n,m
第三行开始共m行,每行一个整数表示wi

Output
输出一行,包含一个整数,表示ans mod p的值(数据保证有解)

Sample Input
100
4 2
1
2

Sample Output
12

20%的数据n<=10,p为素数
70%的数据n<=10^5,p为素数
100%的数据n,p<=10^9,m<=5
p=p1^c1*p2^c2*…*pt^ct,pi为质数,保证pi^ci<=10^5

看题第一眼:这是一个人畜无害的题目,求个组合数就可以了。
恩,这么做,送你20分。

第二眼:n<=10^5,p为素数,可以用lucas定理。
{引用百度百科}

数论Lucas定理是用来求 c(n,m) mod p的值,p是素数(从n取m组合,模上p)。
描述为:
Lucas(n,m,p)=cm(n%p,m%p)* Lucas(n/p,m/p,p) 【照顾一下pascal选手 %=mod,/=div】
Lucas(x,0,p)=1;

cm(a,b)=a! * (b!*(a-b)!)^(p-2) mod p
也= (a!/(a-b)!) * (b!)^(p-2)) mod p
这里,其实就是直接求 (a!/(a-b)!) / (b!) mod p
由于 (a/b) mod p = a * b^(p-2) mod p

这么做一遍,可以拿个70分。

剩下的30分,看数据p=p1^c1*p2^c2*…*pt^ct,p不为素数,那就不能用lucas定理了。
怎么做呢。
再仔细看一下数据pi为质数,而且pi^ci<=10^5,那么我们可以分解一下质因数,最后用剩余定理合并一下答案就可以了。
{附上剩余定理}

中国剩余定理:
设 m1,m2,…,mk 是两两互素的正整数,即 gcd(mi,mj) =1,i≠j,i,j = 1,2,…,k
则同余方程组:
x≡b1 (mod m1)
x≡b2 (mod m2)

x≡bk (mod mk)
模[m1,m2,…,mk]有唯一解,即在[m1,m2,…,mk]的意义下,存在唯一的 x,满足:
x≡bi mod [m1,m2,…,mk],i = 1,2,…,k
X=∑ bi ∗((p/mi)^−1)∗ (p/mi) mod p

注意1: (p/mi)^−1是(p/mi) 对于 mi 的乘法逆元
即设(p/mi)^-1为n,则n*(p/mi) mod mi=1

【求逆元,我们用扩展gcd跑一遍就可以了。】
{扩展gcd比较简单,不会的百度一下}

注意2:对于最终结果,X应mod p。(不保证数据不会有坑)

分析出思路,我们再来分析一下题目中每个Cnw[i],发现它们可以合并成一个分式:

n!

w[1]!w[2]!w[3]!………(1-w[1]-w[2]-w[3]-w[4]-…-w[m])!

然后我们将这个式子取模,最后合并,就大功告成了。

想的不错,但还有两个问题:
1.对于n!我们要怎么办,不可能暴力算出结果。
2.对于除法不能直接取模

回答:1.引用题解

对于 n! mod pi^ci, 我们可以把 n!分组 1~pi-1 、pi+1~2pi-1…… 和 pi 的倍数
注意到 第二组 为 (1+pi),(2+pi)……
把式子展开 得到 (pi-1)!+(pi 的倍数),意味着每组的乘积在 mod pi 下相等
Pi 的倍数都提出一个 pi 得到 (n div pi)!*(pi)^(n div pi)
前项递归处理,后项用变量记录
预处理(pi-1)!的值
这样我们就能用快速幂算出 n!mod pi 的值 复杂度大约为 O(logn*logn+pi^ci)

需要注意的是题解有点问题,即n不一定恰好是pi的倍数,我们要暴力处理一下最后长度不足pi的一段。

回答2.对于除法,我们将它们转换为乘法。
只需要用同样的方法处理w[i]!,然后用扩展gcd求一下逆元,相乘后取模就可以了。

至此,所有问题都已解决。

总结一下:本题是一道数学题,而且需要用很多的时间去分析,还要掌握很多的定理。
对于这种题,不要太纠结,拿个70分就够了。在做完别的题以后再来思考。
要试着从题目中尽可能地发现线索,如本题的数据范围就是一个很好的引子

0 0
原创粉丝点击