您的位置:首页 > 其它

礼物

2015-08-11 16:41 204 查看
礼物

节日到了,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分就够了。在做完别的题以后再来思考。

要试着从题目中尽可能地发现线索,如本题的数据范围就是一个很好的引子
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: