令 s u m ( p , k ) = ( p 0 + p 1 + . . . + p k ) % sum(p,k) = (p^{0} + p^{1} + ... + p^{k}) sum(p,k)=(p0+p1+...+pk) % M O D \%MOD %MOD
如何快速求出它的值?
首先当 k % k k 为奇数时,我们可以将指数划分为两部分(因为有0次方,指数的个数为偶数个),如下所示:
s
u
m
(
p
,
k
)
% sum(p,k)
sum(p,k)
=
p
0
+
p
1
+
.
.
.
+
p
k
% = p^{0} + p^{1} + ... + p^{k}
=p0+p1+...+pk
=
(
p
0
+
p
1
+
.
.
.
+
p
k
/
2
)
+
(
p
k
/
2
+
1
+
p
k
/
2
+
2
+
.
.
.
+
p
k
)
% = (p^{0} + p^{1} + ... + p^{k/2}) + (p^{k/2+1} + p^{k/2+2} + ... + p^{k})
=(p0+p1+...+pk/2)+(pk/2+1+pk/2+2+...+pk)
=
(
p
0
+
p
1
+
.
.
.
+
p
k
/
2
)
+
p
k
/
2
+
1
∗
(
p
0
+
p
1
+
.
.
.
+
p
k
/
2
)
% = (p^{0} + p^{1} + ... + p^{k/2}) + p^{k/2+1} * (p^{0} + p^{1} + ... + p^{k/2})
=(p0+p1+...+pk/2)+pk/2+1∗(p0+p1+...+pk/2)
=
(
p
0
+
p
1
+
.
.
.
+
p
k
/
2
)
∗
(
1
+
p
k
/
2
+
1
)
% = (p^{0} + p^{1} + ... + p^{k/2}) * (1 + p^{k/2+1})
=(p0+p1+...+pk/2)∗(1+pk/2+1)
=
s
u
m
(
p
,
k
/
2
)
∗
(
1
+
p
k
/
2
+
1
)
% = sum(p,k/2) * (1 + p^{k/2+1})
=sum(p,k/2)∗(1+pk/2+1)
当 k % k k 为偶数时,我们无法直接将指数划分为两部分(因为有0次方,指数的个数为奇数个),所以我们可以采取如下方法,让 k % k k 递归成奇数:
s
u
m
(
p
,
k
)
% sum(p,k)
sum(p,k)
=
p
0
+
p
1
+
p
2
+
.
.
.
+
p
k
% = p^{0} + p^{1} + p^{2} + ... + p^{k}
=p0+p1+p2+...+pk
=
p
0
+
(
p
1
+
p
2
+
.
.
.
+
p
k
)
% = p^{0} + (p^{1} + p^{2} + ... + p^{k})
=p0+(p1+p2+...+pk)
=
p
0
+
p
1
∗
(
p
0
+
p
1
+
.
.
.
+
p
k
−
1
)
% = p^{0} + p^{1} * (p^{0} + p^{1} + ... + p^{k-1})
=p0+p1∗(p0+p1+...+pk−1)
=
p
0
+
p
1
∗
s
u
m
(
p
,
k
−
1
)
% = p^{0} + p^{1} * sum(p,k-1)
=p0+p1∗sum(p,k−1)
=
1
+
p
∗
s
u
m
(
p
,
k
−
1
)
% = 1 + p * sum(p,k-1)
=1+p∗sum(p,k−1) ——其中
k
−
1
% k - 1
k−1 为奇数
代码如下
int sum(int p,int k)
{
if(k == 0) return 1;
if(k % 2 == 0)
{
//当k为偶数时 sum(p,k) = 1 + p * sum(p, k-1)
return (1 + p % MOD * sum(p, k - 1)) % MOD;
}
//当k为奇数时 sum(p,k) = sum(p, k / 2) * (1 + p^(k / 2 + 1) )
return sum(p, k / 2) * (1 + pow(p, k / 2 + 1)) % MOD;
}