• ZOJ3774_Power of Fibonacci


    求fibonacci数列前N个数的K次方和。

    通项公式:F[n]=((1+sqrt(5))/sqrt(5)-(1-sqrt(5))/sqrt(5))/sqrt(5)。

    有点乱,不过由于可以保证最后的结果是一个整数,所有所有的根号都可以化为整数进行取模和逆元运算。

    首先解二次同余方程,X^2=n (mod M),显然,当n=5的时候,X就可以相当于5了。

    后面的都可以替换掉。

    然后就变成了 F[n]=(A^n+B^n)*C。

    这里通过二项式展开,分别对每一项进行计算,同时又可以发现,每一项求和其实是一个等比数列,于是,就可以直接搞了。

    召唤代码君:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #define M 1000000009
    #define maxn 100100
    typedef long long ll;
    using namespace std;
    
    ll w,a,m,root,inv;
    ll A[maxn],B[maxn];
    ll n,k,ans,cur,now;
    ll AAA,BBB;
    int T;
    
    struct twice{
        ll A,B;
        twice() {}
        twice(ll AA,ll BB) { A=AA,B=BB; }
        void mul(twice T){
            ll aa=A*T.A+(B*T.B)%M*w,bb=A*T.B+B*T.A;
            A=aa%M,B=bb%M;
        }
    };
    
    ll power(ll A,ll B,ll C)
    {
        ll tot=1;
        while (B){
            if (B&1) tot=tot*A%C;
            A=A*A%C,B>>=1;
        }
        return tot;
    }
    
    twice power(twice T,ll y)
    {
        twice C(1,0);
        while (y){
            if (y&1) C.mul(T);
            T.mul(T),y>>=1;
        }
        return C;
    }
    
    ll getroot()
    {
        for (;;){
            a=rand()%M;
            w=(a*a-5+M)%M;
            if (power(w,M/2,M)!=1) break;
        }
        return power(twice(a,1),(M+1)/2).A;
    }
    
    void _init()
    {
        root=getroot();
        A[0]=B[0]=1;
        for (int i=1; i<maxn; i++){
            A[i]=(A[i-1]*i)%M;
            B[i]=power(A[i],M-2,M);
        }
        inv=B[2];
        AAA=(1+root)*inv%M;
        BBB=(M+1-root)*inv%M;
    }
    
    int main()
    {
        _init();
        scanf("%d",&T);
        while (T--){
            scanf("%lld%lld",&n,&k);
            ans=0;
            for (int i=0; i<=k; i++){
                cur=A[k]*(B[i]*B[k-i]%M)%M;
                if (i&1) cur=M-cur;
                now=power(AAA,k-i,M)*power(BBB,i,M)%M;
                if (now>1) now=((power(now,n+1,M)-now)*power(now-1,M-2,M)%M+M)%M;
                    else now=now*n%M;
                (ans+=cur*now)%=M;
            }
            ans=ans*power(root,k*(M-2),M)%M;
            printf("%d
    ",(int)ans);
        }
        return 0;
    }
  • 相关阅读:
    《DSP using MATLAB》Problem 6.17
    一些老物件
    《DSP using MATLAB》Problem 6.16
    《DSP using MATLAB》Problem 6.15
    《DSP using MATLAB》Problem 6.14
    《DSP using MATLAB》Problem 6.13
    《DSP using MATLAB》Problem 6.12
    《DSP using MATLAB》Problem 6.11
    P1414 又是毕业季II
    Trie树
  • 原文地址:https://www.cnblogs.com/lochan/p/3886884.html
Copyright © 2020-2023  润新知