数论 - 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} F0=0,F1=1Fn=Fn1+Fn2(n>1)

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

( F 1 ) K + ( F 2 ) K + ( F 3 ) K + . . . + ( F N ) K (F_1)^K+(F_{2})^K+(F_{3})^K+...+(F_{N})^K (F1)K+(F2)K+(F3)K+...+(FN)K

答 案 对 1 0 9 + 9 取 模 。 答案对10^9+9取模。 109+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] Fn=5 1[(21+5 )n(215 )n]

首 先 , 5 是 模 数 1 0 9 + 9 的 首先,5是模数10^9+9的 5109+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。 x25 mod 109+9 x 5  mod 109+9

计 算 得 到 一 个 满 足 条 件 的 x = 383008016 计算得到一个满足条件的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) 5 1276601605 (mod 109+9),21+5 691504013 (mod 109+9),215 308495997 (mod 109+9)

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

原 式 等 价 于 对 数 列 : 原式等价于对数列:

F n k = D k ( a n − b n ) k F_n^k=D^k(a^n-b^n)^k Fnk=Dk(anbn)k

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

观 察 ( a n − b n ) k , 根 据 二 项 式 展 开 : 观察(a^n-b^n)^k,根据二项式展开: (anbn)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 (anbn)k=Ck0(an)k(bn)0(1)0+Ck1(an)k1(bn)1(1)1+...+Ckr(an)kr(bn)r(1)r+...+Ckk(an)0(bn)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,上式转化为: (1)rCkr=MrSnr=(an)kr(bn)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} (anbn)k=M0Sn0+M1Sn1+...+MrSnr+...+MkSnk

则 : 则: :

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}) Fnk=Dk(M0Sn0+M1Sn1+...+MkSnk)

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

原 式 等 价 于 : 原式等价于:

( F 1 ) k + ( F 2 ) k + . . . + ( F N ) k (F_{1})^k+(F_{2})^k+...+(F_{N})^k (F1)k+(F2)k+...+(FN)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}) =M0(i=1NS(i)0)+M1(i=1NS(i)1)+...+Mk(i=1NS(i)k)

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

公 比   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}  q=SiSi+1=(ai)kr(bi)r(ai+1)kr(bi+1)r=a(kr)br

则 数 列 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 SiQ=a(kr)brS1=a(kr)br=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} Sii=1NSi=Q1Q(Qn1)

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

∑ 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}。 r=0kMr(i=1NSi)=r=0k(1)rCkr(Q1Q(Qn1))Q=a(kr)br

注意:

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即可。 Q=1i=1NSi=N(1)rCkr×N

具体细节:

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

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

优化:

  • 观 察 相 邻 两 项 的 公 比 : 观察相邻两项的公比:

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

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

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

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

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

时间复杂度: O ( T k l o g ( m o d ) ) . O(Tklog(mod)). 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值