[算法题]等比数列快速求和取模

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+...+pk1)
= p 0 + p 1 ∗ s u m ( p , k − 1 ) % = p^{0} + p^{1} * sum(p,k-1) =p0+p1sum(p,k1)
= 1 + p ∗ s u m ( p , k − 1 ) % = 1 + p * sum(p,k-1) =1+psum(p,k1) ——其中 k − 1 % k - 1 k1 为奇数

代码如下

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;
}
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值