组合数取模的各种方法

来源:互联网 发布:c语言如何产生随机数 编辑:程序博客网 时间:2024/06/05 17:24

借用一下kqp学长的ppt
这里写图片描述

Lucas定理

这里写图片描述
预处理前缀和计算小于105的C.

中国剩余定理

这里写图片描述

终于到我自己写了

那么现在求的是Cmn modpc的值。
拆出式子,n(n1)...(nm+1)m!
由于pc不一定与1..n的数互质,所以可能没有逆元。因此我们要避免除法,先将所有p提出,将原式写为

pk  jc(n)jc1(nm)jc1(m)

jc(x)表示的是x!p mod pc
jc1(x)表示的是jc(x)关于pc的逆元。

Part1. 求k的值

这个可以分治着做。 设g(n)表示n!含有的p的指数和(k)。
g(n)=g(np)+np
因为p至少是2,所以O(logn)

part2.求jc(n)的值

我们依旧分治着求。
jc(n)=sum(n)+jc(np),设sum(n)为1..n中与q互质的数的乘积%p^c.

稍微解释一下,n!去掉所有p=是所有与p互质的数的乘积 * 与p不互质的数去掉所有p
不互质的数就是p,2p...,提出一个被去掉的p也就是1,2...np
那么sum怎么求呢? 可以用mod pc的循环节快速求。

时间复杂度分析

不难看出,求解时间就是O(logp+ pc),比较昂贵,特别是在p为一个大质数乘上小质数时。

不要方,可以发现,当c=1时,可以直接套用Lucas定理求解Cmn modp
又因为对于一般小于等于sqrt(2^61)约等于10^10次方的模数,若c>1,则p不会大于105,因此时间复杂度我们可以视为105数量级的。虽然还是很大..

更优的方法?

似乎暂时无法理解。 所以留坑,丢个吼文链接

author: skywalkert
original article: http://blog.csdn.net/skywalkert/article/details/52553048
last update time : 2017-03-30

原创粉丝点击