数论 - Power of Fibonacci - ZOJ 3774

数论 - Power of Fibonacci - ZOJ 3774

题意:

斐波那契数列:

{ F 0 = 0 , F 1 = 1 F n = F n 1 + F n 2 ( n > 1 ) \begin{cases}F_0=0,F_1=1\\\\F_n=F_{n-1}+F_{n-2}(n>1)\end{cases}

N K 给定正整数N、K,计算:

( F 1 ) K + ( F 2 ) K + ( F 3 ) K + . . . + ( F N ) K (F_1)^K+(F_{2})^K+(F_{3})^K+...+(F_{N})^K

1 0 9 + 9 答案对10^9+9取模。

Input

There are multiple test cases. The first line of input is an integer T indicates the number of test cases. For each test case:

There are two integers N and K (0 ≤ N ≤ 1018, 1 ≤ K ≤ 100000).

Output

For each test case, output the remainder of the answer divided by 1000000009.

Sample Input

5
10 1
4 20
20 2
9999 99
987654321987654321 98765

Sample Output

143
487832952
74049690
113297124
108672406

分析:

斐波那契数列的通项公式:

F n = 1 5 [ ( 1 + 5 2 ) n ( 1 5 2 ) n ] F_n=\frac{1}{\sqrt{5}}[(\frac{1+\sqrt{5}}{2})^n-(\frac{1-\sqrt{5}}{2})^n]

5 1 0 9 首先,5是模数10^9的 二次剩余

x 2 5   m o d   1 0 9 + 9   x   5   m o d   1 0 9 + 9 即用满足:x^2≡5\ mod\ 10^9+9\ 的x来代替\ \sqrt{5}\ mod\ 10^9+9。

x = 383008016 计算得到一个满足条件的x=383008016

则: 1 5 276601605   ( m o d   1 0 9 + 9 ) , 1 + 5 2 691504013   ( m o d   1 0 9 + 9 ) , 1 5 2 308495997   ( m o d   1 0 9 + 9 ) \frac{1}{\sqrt{5}}≡276601605\ (mod\ 10^9+9),\frac{1+\sqrt{5}}{2}≡691504013\ (mod\ 10^9+9),\frac{1-\sqrt{5}}{2}≡308495997\ (mod\ 10^9+9)

D = 276601605 a = 691504013 b = 308495997 令D=276601605,a=691504013,b=308495997,

原式等价于对数列:

F n k = D k ( a n b n ) k F_n^k=D^k(a^n-b^n)^k

1 0 9 的部分项求和并对10^9取模。

( a n b n ) k 观察(a^n-b^n)^k,根据二项式展开:

( a n b n ) k = C k 0 ( a n ) k ( b n ) 0 ( 1 ) 0 + C k 1 ( a n ) k 1 ( b n ) 1 ( 1 ) 1 + . . . + C k r ( a n ) k r ( b n ) r ( 1 ) r + . . . + C k k ( a n ) 0 ( b n ) k ( 1 ) k (a^n-b^n)^k=C_k^0(a^n)^k(b^n)^0(-1)^0+C_k^1(a^n)^{k-1}(b^n)^1(-1)^1+...+C_k^r(a^n)^{k-r}(b^n)^r(-1)^r+...+C_k^k(a^n)^0(b^n)^k(-1)^k

( 1 ) r C k r = M r S n r = ( a n ) k r ( b n ) r 记(-1)^rC_k^r=M_r,S_{nr}=(a^{n})^{k-r}(b^{n})^r,上式转化为:

( a n b n ) k = M 0 S n 0 + M 1 S n 1 + . . . + M r S n r + . . . + M k S n k (a^n-b^n)^k=M_0S_{n0}+M_1S_{n1}+...+M_rS_{nr}+...+M_kS_{nk}

: 则:

F n k = D k ( M 0 S n 0 + M 1 S n 1 + . . . + M k S n k ) F_{n}^k=D^k(M_0S_{n0}+M_1S_{n1}+...+M_kS_{nk})

n S n r M r 不论n取何值,S_{nr}前的系数均相同,为M_r,

原式等价于:

( F 1 ) k + ( F 2 ) k + . . . + ( F N ) k (F_{1})^k+(F_{2})^k+...+(F_{N})^k

= M 0 ( i = 1 N S ( i ) 0 ) + M 1 ( i = 1 N S ( i ) 1 ) + . . . + M k ( i = 1 N S ( i ) k ) =M_0(\sum_{i=1}^NS_{(i)0})+M_1(\sum_{i=1}^NS_{(i)1})+...+M_k(\sum_{i=1}^NS_{(i)k})

k 1 0 5 0 k r r S i i 本题k≤10^5,可以从0到k枚举r,而当r为常数时,S_i是一个关于i的等比数列,

  q = S i + 1 S i = ( a i + 1 ) k r ( b i + 1 ) r ( a i ) k r ( b i ) r = a ( k r ) b r 公比\ q=\frac{S_{i+1}}{S_{i}}=\frac{(a^{i+1})^{k-r}(b^{i+1})^r}{(a^{i})^{k-r}(b^{i})^r}=a^{(k-r)}b^{r}

S i Q = a ( k r ) b r S 1 = a ( k r ) b r = Q 则数列S_{i}的公比为Q=a^{(k-r)}b^{r},首项为S_{1}=a^{(k-r)}b^{r}=Q

S i i = 1 N S i = Q ( Q n 1 ) Q 1 等比数列S_i求和:\sum_{i=1}^NS_i=\frac{Q(Q^n-1)}{Q-1}

r M r ( i = 1 N S i ) 因此,我们可以通过枚举r对M_r(\sum_{i=1}^NS_i)求和,即计算:

r = 0 k M r ( i = 1 N S i ) = r = 0 k ( 1 ) r C k r ( Q ( Q n 1 ) Q 1 ) Q = a ( k r ) b r \sum_{r=0}^kM_r(\sum_{i=1}^NS_i)=\sum_{r=0}^k(-1)^rC_k^r(\frac{Q(Q^n-1)}{Q-1}),其中Q=a^{(k-r)}b^{r}。

注意:

Q = 1 i = 1 N S i = N ( 1 ) r C k r × N Q=1时,\sum_{i=1}^NS_i=N,直接累加(-1)^rC_k^r×N即可。

具体细节:

C r k C k r = k ! r ! ( k r ) ! k ! ①、求组合数C_r^k可以通过定义,C_k^r=\frac{k!}{r!·(k-r)!}来解决,需要预处理k!和对应的逆元。

a b r Q ②、将a、b带入,对枚举的每一个r,用快速幂求具体的Q。

优化:

  • 观察相邻两项的公比:

Q = a k r b r \qquad Q=a^{k-r}b^{r}\qquad\qquad\qquad①

Q = a k ( r + 1 ) b r + 1 \qquad Q=a^{k-(r+1)}b^{r+1}\qquad②

× ( b a ) = \qquad发现,①×-(\frac{b}{a})=②

\qquad因此,我们可以通过递归由①推②,减少快速幂的计算。

  • p = 1 0 9 + 9 a p 1 1 ( m o d   p ) 费马小定理:模数p=10^9+9是质数,可以通过费马小定理a^{p-1}≡1(mod\ p),优化快速幂。

时间复杂度: O ( T k l o g ( m o d ) ) . O(Tklog(mod)).


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define ll long long

using namespace std;

const int N=1e5, mod=1e9+9;
const int a=691504013, b=308495997, D=276601605;

int fac[N+10],inv[N+10];

int quick_pow(ll a,ll b,int mod)
{
    int res=1;
    a%=mod;
    while(b)
    {
        if(b&1) res=(ll)res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}

void Init()
{
    fac[0]=1;
    for(int i=1;i<=N;i++) fac[i]=(ll)fac[i-1]*i%mod;
    for(int i=0;i<=N;i++) inv[i]=quick_pow(fac[i],mod-2,mod);
}

int INV(int x)
{
    return quick_pow(x,mod-2,mod);
}

int C(int n,int m)
{
    if(n<m) return 0;
    return (ll)fac[n]*inv[m]%mod*inv[n-m]%mod;
} 

int Sum(ll n,int k)
{
    ll ans=0;
    int an=quick_pow(a,k,mod), //an初始值为a^ck
        bn=1;   //bn初始值为b^0
    int ainv=INV(a);   //a逆元
    
    for(int r=0;r<=k;r++)
    {
        int Q=(ll)an*bn%mod, S;
        
        int Ckr=C(k,r);
        if(r&1) Ckr=-Ckr;
        
        if(Q==1) S=n%mod;
        else S=(ll)Q*(quick_pow(Q,n%(mod-1),mod)-1)%mod*INV(Q-1)%mod;
        S=(ll)Ckr*S%mod;

        ans+=S;
        an=(ll)an*ainv%mod;
        bn=(ll)bn*b%mod;
    }
    
    ans=(ans%mod+mod)*quick_pow(D,k,mod)%mod;
        
    return ans;
}

int main()
{
    Init();

    int T,k;
    ll n;
    cin>>T;
    while(T--)
    {
        scanf("%lld%d",&n,&k);
        printf("%d\n",Sum(n,k));
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/njuptACMcxk/article/details/107524245