等比数列

看了这位学长的博客,所以想要记录一下其中涉及到的如何快速求等比数列的和(矩阵快速幂也可以快速求出,这里就不写了);

链接:https://blog.csdn.net/keepcoral/article/details/80144750

假设我们现在知道了a1,q,n,叫我们求等比数列的和,如果这个和非常大,需要取模,所以我们也知道了mod。

即a1,q,n,mod是已知的。

补充一下数学知识,有时候吧我也会忘记:

an=a1*q^(n-1),等比数列的和Sn=a1+a1*q+a1*q^2+...+a1*q^(n-1)=a1*(1+q+q^2+...+q^(n-1))=a1*(1-q^n)/(1-q);

                这里主要是上面的这两个加粗的公式

在求和的时候我们先把a1提出来,咱们先算(1+q+q^2+...+q^(n-1)),这里主要是二分的思想

ll T(ll q,ll n)
{
    if(n==1)
    return 1;
    ll date=T(q,n/2)%mod;//step1
    date=(date+date*quick(q,n/2))%mod;//step2
    if(n%2)
    date=(date+quick(q,n-1))%mod;//step3
    return date;
}

我在这里再添加一个例子:假如n为15;当递归到n==1时我们回溯;

递归顺序是n=15,n=7,n=3,n=1;

我们要求1+q+q^2+q^3+...+q^14;

我们回溯(退回去)。

n==3,step1:date=1        step2:date=1+q          step3date=1+q+q^2;

n==7,  step1:date=1+q+q^2       step2:date=1+q+q^2+q^3+q^4+q^5   step3:date=1+q+q^2+q^3+q^4+q^5+q^6

太长了,偷个懒

n==15,step1:date=1+...+q^6      step2:date=1+...+q^6+...+q^13   step3:date=1+...+q^14;

看上面的step1,step2,step3三个过程应该可以理解了吧。

代码:

#include<stdio.h>
#include<string.h>
#define mod 10000007
#define ll long long
ll n,m,k,t;
ll quick(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
        ans=a*ans%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
ll T(ll q,ll n)
{
    if(n==1)
    return 1;
    ll date=T(q,n/2)%mod;
    date=(date+date*quick(q,n/2))%mod;
    if(n%2)
    date=(date+quick(q,n-1))%mod;
    return date;
}
int main()
{
    ll q,n,a1;
    scanf("%lld%lld%lld",&a1,&q,&n);
    ll ans=T(q,n);
    ans=ans*a1%mod;
    printf("%lld",ans);
    return 0;
 } 
原文地址:https://www.cnblogs.com/6262369sss/p/8973446.html