Fibonacci Sum (HDU - 6755,斐波那契数列幂之和 + 亿点小优化)

一.题目链接

\quad Fibonacci Sum

二.题目大意

\quad T组数据,每次给出三个整数 N,C,K,求 ∑ i = 0 N f i b i × C K   ( m o d   1 0 9 + 9 ) \sum_{i=0}^{N}fib_{i \times C}^K \ (mod \ 10^9+9) i=0Nfibi×CK (mod 109+9).
\quad 1 ≤ T ≤ 1 0 2 , 1 ≤ N , C ≤ 1 0 18 , 1 ≤ K ≤ 1 0 5 1 \leq T \leq 10^2, 1 \leq N,C \leq 10^{18}, 1 \leq K \leq 10^5 1T102,1N,C1018,1K105.

三.分析

\quad 根据斐波那契数列通项公式 f i b n = 1 5 [ ( 1 + 5 2 ) i × C − ( 1 − 5 2 ) i × C ] fib_n = \frac{1}{\sqrt5} \left[ \left( \frac{1+\sqrt5}{2} \right)^{{i \times C}} - \left( \frac{1-\sqrt5}{2} \right)^{i \times C} \right] fibn=5 1[(21+5 )i×C(215 )i×C],可得下式

\quad ∑ i = 0 N f i b i × C K = ∑ i = 0 N { 1 5 [ ( 1 + 5 2 ) i × C − ( 1 − 5 2 ) i × C ] } K = ( 1 5 ) K ∑ i = 0 N [ ( 1 + 5 2 ) i × C − ( 1 − 5 2 ) i × C ] K \begin{aligned} \sum_{i=0}^{N}fib_{i \times C}^K &= \sum_{i=0}^{N} \left\{ \frac{1}{\sqrt5} \left[ \left( \frac{1+\sqrt5}{2} \right)^{{i \times C}} - \left( \frac{1-\sqrt5}{2} \right)^{i \times C} \right] \right\}^K \\ &= \left( \frac{1}{\sqrt5} \right)^K \sum_{i=0}^{N} \left[ \left( \frac{1+\sqrt5}{2} \right)^{{i \times C}} - \left( \frac{1-\sqrt5}{2} \right)^{i \times C} \right]^K \end{aligned} i=0Nfibi×CK=i=0N5 1(21+5 )i×C(215 )i×CK=(5 1)Ki=0N(21+5 )i×C(215 )i×CK

\quad p = 1 0 9 + 9 , a = 1 + 5 2   ( m o d   p ) , b = 1 − 5 2   ( m o d   p ) , c = 1 5   ( m o d   p ) p = 10^9 + 9, a=\frac{1+\sqrt5}{2} \ (mod \ p), b = \frac{1-\sqrt5}{2} \ (mod \ p), c = \frac{1}{\sqrt5} \ (mod \ p) p=109+9,a=21+5  (mod p),b=215  (mod p),c=5 1 (mod p)

\quad 使用小学知识二次剩余和费马小定理可得 a = 308495997 , b = 691504013 , c = 723398404 a=308495997, b = 691504013, c = 723398404 a=308495997,b=691504013,c=723398404.

\quad 于是 ∑ i = 0 N f i b i × C K = c K ∑ i = 0 N ( a i × C − b i × C ) K \begin{aligned} \sum_{i=0}^{N} fib_{i \times C}^K= c^K\sum_{i=0}^N\left( a^{i \times C} - b^{i \times C} \right)^K \end{aligned} i=0Nfibi×CK=cKi=0N(ai×Cbi×C)K.

\quad 根据幼儿园学的二项式定理展开可得 ∑ i = 0 N f i b i × C K = c K ∑ i = 0 N ∑ j = 0 K ( K j ) ( − 1 ) j ( b i C ) j ( a i C ) K − j \begin{aligned} \sum_{i=0}^{N} fib_{i \times C}^K= c^K\sum_{i=0}^N \sum_{j=0}^{K} \left( \begin{matrix} K \\ j \end{matrix}\right) (-1)^{j} \left( b^{iC}\right)^j \left( a^{iC}\right)^{K - j} \end{aligned} i=0Nfibi×CK=cKi=0Nj=0K(Kj)(1)j(biC)j(aiC)Kj

\quad 整理一下

\quad ∑ i = 0 N f i b i × C K = c K ∑ i = 0 N ∑ j = 0 K ( K j ) ( − 1 ) j ( b i C ) j ( a i C ) K − j = c K ∑ j = 0 K ( K j ) ( − 1 ) j ∑ i = 0 N [ b j C a ( K − j ) C ] i \begin{aligned} \sum_{i=0}^{N} fib_{i \times C}^K &= c^K\sum_{i=0}^N \sum_{j=0}^{K} \left( \begin{matrix} K \\ j \end{matrix}\right) (-1)^{j} \left( b^{iC}\right)^j \left( a^{iC}\right)^{K - j} \\ &= c^K \sum_{j=0}^{K} \left( \begin{matrix} K \\ j \end{matrix}\right) (-1)^{j} \sum_{i=0}^N \left[ b^{jC} a^{(K - j)C} \right]^i \end{aligned} i=0Nfibi×CK=cKi=0Nj=0K(Kj)(1)j(biC)j(aiC)Kj=cKj=0K(Kj)(1)ji=0N[bjCa(Kj)C]i

\quad t j = [ b j C a ( K − j ) C ] i t_j = \left[ b^{jC} a^{(K - j)C} \right]^i tj=[bjCa(Kj)C]i,根据等比数列求和公式得

\quad ∑ i = 0 N f i b i × C K = { c K ∑ j = 0 K ( K j ) ( − 1 ) j ( N + 1 ) ,   t j = 1 c K ∑ j = 0 K ( K j ) ( − 1 ) j t j N + 1 − 1 t j − 1 ,   t j ≠ 1 \begin{aligned} \sum_{i=0}^{N} fib_{i \times C}^K &= \left\{ \begin{matrix} c^K \sum_{j=0}^{K} \left( \begin{matrix} K \\ j \end{matrix}\right) (-1)^{j} (N + 1), \ t_j =1 \\ c^K \sum_{j=0}^{K} \left( \begin{matrix} K \\ j \end{matrix}\right) (-1)^{j} \frac{t_j^{N + 1} - 1}{t_j - 1} , \ t_j \not=1 \end{matrix} \right. \end{aligned} i=0Nfibi×CK=cKj=0K(Kj)(1)j(N+1), tj=1cKj=0K(Kj)(1)jtj1tjN+11, tj=1

\quad 至此,这道题的大体做法就口胡完了.

\quad 这道题比较卡时间,因此我们可以预处理一些东西,同时维护某些量,总的时间复杂度为 O ( 1 0 5 l o g 1 0 9 + T K l o g 1 0 9 ) O(10^5log10^9 + TKlog10^9) O(105log109+TKlog109).

四.代码实现

#include 
using namespace std;

typedef long long ll;

const int M = (int)1e5;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)1e9 + 9;
const double eps = 1e-6;
const ll a = 308495997, b = 691504013, c = 723398404;

ll fac[M + 5], invfac[M + 5], ck[M + 5];
ll ack[M + 5], bck[M + 5];

ll quick(ll a, ll b, ll p = mod)
{
    ll s = 1;
    while(b)
    {
        if(b & 1) s = s * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return s;
}

ll inv(ll n, ll p = mod)
{
    return quick(n, p - 2, p);
}

ll C(int n, int m)
{
    return fac[n] * invfac[m] % mod * invfac[n - m] % mod;
}

void work()
{
    ll N, C, K; scanf("%lld %lld %lld", &N, &C, &K);
    ll ac = quick(a, C), bc = quick(b, C);
    ack[0] = 1, bck[0] = 1;
    for(int i = 1; i <= K; ++i)
    {
        ack[i] = ack[i - 1] * ac % mod;
        bck[i] = bck[i - 1] * bc % mod;
    }
    ll acn = quick(quick(a, C), N + 1), bcn = quick(quick(b, C), N + 1);
    ll invacn = inv(acn), invbcn = inv(bcn);
    ll nowacn = quick(acn, K), nowbcn = 1;
    ll s = 0, m = (N + 1) % mod, w, t;
    for(int i = 0; i <= K; ++i)
    {
        w = ::C(K, i); if(i & 1) w = -w % mod;
        t = ack[K - i] * bck[i] % mod;
        if(t == 1)  w = w * m % mod;
        else        w = w * (nowacn * nowbcn % mod - 1) % mod * inv(t - 1) % mod;
        s = (s + w) % mod;
        nowacn = nowacn * invacn % mod, nowbcn = nowbcn * bcn % mod;
    }
    s = s * ck[K] % mod;
    s = (s % mod + mod) % mod;
    printf("%lld\n", s);
}

int main()
{
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    fac[0] = invfac[0] = ck[0] = 1;
    for(int i = 1; i <= M; ++i)
    {
        fac[i] = fac[i - 1] * i % mod;
        invfac[i] = inv(fac[i]);
        ck[i] = ck[i - 1] * c % mod;
    }
    int T; scanf("%d", &T);
    while(T--) work();
    return 0;
}

你可能感兴趣的:(#,求和)