题目描述
给定
n,p,k
,其中
p
是质数。
求
题目保证答案是
PQ
的形式,且
Q−1
,即
Q
对
npk≤1018
p≤105
分析
先考虑所有变量的范围
k≤70
n≤1018
类似于求 n!modp 的思路。
∑ni=11i=1p∑⌊np⌋i=11i+∑0<a<p,a+bp≤n1a+bp
那么这个式子的计算就分成了两个部分。
part 1
1p∑⌊np⌋i=11i(modpk)
假如我们可以处理好
1p
的问题,那么剩下的递归计算就可以了。
考虑计算
∑⌊np⌋i=11i(modpk+1)
那么由于题目保证了答案逆元存在,所以
1p∑⌊np⌋i=11i=∑⌊np⌋i=11imodpk+1p(modpk)
分子必定含有 p 的因子,具体证明的话,
结合这个式子倒推一下就可以得到了。
part 2
∑0<a<p,a+bp≤n1a+bp
现在要处理的就是快速地计算
∑(a+bp)−1
考虑按
a
分组,推导
考虑
11−x=x0+x1+x2+⋯
那么
原式=∑⌊n−ap⌋b=0∑+∞k=0(−bpa)ka=∑⌊n−ap⌋b=0∑+∞i=0(−bpa)ia(modpk)
由于括号内那项含
p
,因此当
考虑交换枚举顺序,则有
问题成功地转化成了自然数幂求和问题,用矩阵乘法处理一下就可以了。
考虑时间复杂度。
T(n,k)=T(np,k+1)+k3+kP
因此总的时间复杂度上界约为 O(k3lognp+kPlognp)
备注
注意中间可能要有64位整数相乘后取模的过程。
用黑科技就可以跑得飞快了。
附一下黑科技的代码
LL mult( LL A, LL B, LL Mo )
{
LL temp = ( ( LL ) ( ( db ) A*B/Mo+1e-6 ) * Mo );
return A*B - temp;
}