Problem
模板题luogu5282
- 求 n! mod p,p是质数
- 由于是任意模数,所以需要MTT。
nlog2n
- 一种
暴力 的方法是多项式加分块,设定一个块的大小B,以及这样一个多项式:
f(x)=i=1∏B(x+i)
- 那么答案就是f(0)∗f(B)∗f(2B)∗...∗f(n/B∗B)∗最后剩下不超过B的部分的乘积
- 直接利用多项式多点求值可以搞到nlog2n的复杂度。
nlogn
- 直接求系数实在是太慢了,我们可以考虑另一种多项式的优秀处理方法——点值。
- 设fd(x)=∏i=1d(x+i),那么我们最后就是要求所有的fB(iB)
- 利用倍增的思路,如果我们可以做到从fd(0,B..dB)到f2d(0,B..2dB)的乘二的转化,以及加一的转化,那么就可以倍增求出最后的B个点值了
乘二
- 对于fd(0,B...dB),首先需要变成fd(0,B...2dB).
- 然后再在对应位置上乘上fd(d,d+B...,d+2dB),就可以变成f2d(0,B...2dB)
- 考虑第一步需要得到fd(dB...2dB),再综合第二步,都相当于是从fd(iB)变成fd(iB+x)
- 系统化得来说,假设h(i)=fd(iB),那么相当于我们已知h(0..d),要求h(0+x/B,1+x/B..d+x/B)。
- 运用拉格朗日插值:
h(Δ+n)=i=0∑dh(i)j=i∏i−jΔ+n−j
=j=0∏d(Δ+n−j)i=0∑di!(n−i)!h(i)∗(−1)n−i∗Δ+n−i1
- 由于d<=B,所以不会出现Δ+n−j=i的情况。后面可以直接FFT,前面的只需要用双指针扫一遍即可。
加一
- 从fd(0,B..dB)到fd+1(0,B..dB,(d+1)B)直接暴力即可。
时间复杂度
- T(n)=T(n/2)+n log n=T(n log n)
posted @
2020-05-18 21:16
Deep_Thinking
阅读(
241)
评论()
编辑
收藏
举报