zoukankan      html  css  js  c++  java
  • Power of Fibonacci 斐波那契 + 二次剩余

    由hdu多校自闭场衍生出的几题
    题目1
    求$$sum_{I = 1}^nF_i^k (mod 10^9 + 9)$$
    感觉像是矩阵快速幂,其实不是
    (F_{n} = frac{(frac{1+sqrt5}{2})^n- (frac{1-sqrt 5}{2})^n}{sqrt 5})

    因为(383008016^2 equiv 5(mod 10^9 + 9))

    所以(383008016 equiv sqrt 5(mod 10^9+9))

    所以把383008016乘以(inv(5, 10^9+9))得到

    (frac{sqrt 5}{5} equiv 276601605(mod 10^9+9))

    同理

    (frac{1 + sqrt 5}{5}equiv 691504013 (mod 10^9+9))

    (frac{1 - sqrt 5}{5} equiv 308495997(mod 10^9 + 9))

    那么(F_n = 276601605(691504013 ^ n - 308495997 ^ n) ( mod 10^9 + 9))

    (S = frac{sqrt 5}{5}, R_1 = frac{1 + sqrt5}{2}, R_2 = frac{1 - sqrt 5}{2})

    那么(F_n^m = S^m(R_1^n - R_2^n)^m)

    (F_n^m = S^msum_{k = 0} ^m C_m^k(R_1^{nk}R_2^{n(m - k)} * (-1)^{m - k}))

    那么对于斐波那契前n项和为(S^msum_{k =0 } ^m[C_m^k(sum_{j = 1}^nR_1^{jk}R_2^{j(m - k)})*(-1)^{m - k}])

    注意,如果说mod是其他的值,那么久需要用二次剩余求出该模下5的一个剩余

    得到答案后,只需要线性递推出(C(m, i))在mod下的值,以及遍历最外面的循环k,其中内部的小循环是一个等比数列,直接快速幂求即可
    时间复杂度(O(mlogn))
    在求等比数列前n项时不能直接用求和公式(frac{a_1(q - q^n)}{1 - q}),因为q可能为1


    整理一下
    (F_{n} = frac{(frac{1+sqrt5}{2})^n- (frac{1-sqrt 5}{2})^n}{sqrt 5})

    (F_n^m = (frac{1}{sqrt5})^m[(frac{1+sqrt5}{2})^n - (frac{1 - sqrt5}{2})^n]^m)

    (a = (frac{1+sqrt5}{2}),b = (frac{1-sqrt5}{2}))

    那么(F_n^m = (frac{1}{sqrt5})^m[a^n - b^n]^m)

    二项式展开

    (F_n^m = (frac{1}{sqrt5})^msum_{k = 0}^m(-1)^kleft(egin{array}{c} m\kend{array} ight)(a^{m - k}b^k)^n)

    (t_k = a^{m - k}b^k)

    那么(F_n^m = (frac{1}{sqrt5})^msum_{k = 0}^m(-1)^k left(egin{array}{c} m\kend{array} ight)t_k^n)

    那么(sum_{i = 1}^nF_i^m = (frac{1}{sqrt 5})^msum_{k = 0}^m(-1)^kleft(egin{array}{c} m\kend{array} ight)sum_{i = 1}^nt_k^i)

    [sum_{i = 1}^nF_i^m = (frac{1}{sqrt 5})^msum_{k = 0}^m(-1)^kleft(egin{array}{c} m\kend{array} ight)·left{egin{array}{l}frac{t_k(t_k^i - 1)}{t_k - 1} , t_k ot = 1\n, t_k=1end{array} ight. ]

    (mod 10^9+9)情况下,(a equiv 691504013 (mod 10^9+9), bequiv 308495997(mod 10^9 + 9), frac{1}{sqrt5}equiv 276601605(mod 10^9+9))


    #include <iostream>
    #include <cstdio>
    #define ll long long
    using namespace std;
    const int mod = 1e9 + 9;
    const int N = 3e5 + 5; 
    ll S = 723398404, R1 = 308495997, R2 = 691504013; 
    ll F[N], a[N];
    ll pow(ll a, ll b, ll p){
        ll ans = 1; a %= p;
        while(b){
            if(b & 1) ans = ans * a % p;
            a = a * a % p;
            b >>= 1;
        }
        return ans;
    }
    void ex_gcd(ll a, ll b, ll &d, ll &x, ll &y){
        if(!b) {
            d = a, x = 1, y = 0;
            return;
        }
        ex_gcd(b, a % b, d, y, x);
        y -= x * (a / b);
    }
    ll cal(ll a, ll b){ //等比数列前n项和
        if(a == 1) return b % mod;
        ll ans = pow(a, b + 1, mod);
        ans = (ans - a + mod) % mod;
        return ans * pow(a - 1, mod - 2, mod) % mod;    
    }
    ll c[N];
    int main(){
        int t;
        scanf("%d", &t);
        while(t--) {
            ll ans = 0;
            ll n, m;
            c[0] = 1;
            scanf("%lld%lld", &n, &m);
            for(int i = 1; i <= m; i++) {// 线性求C(m, i)
                ll d, x, y;
                ex_gcd(i, mod, d, x, y); // 求i对mod的逆元
                x = (x % mod + mod) % mod;
                c[i] = (c[i - 1] * x) % mod;
                c[i] = (c[i] * (m - i + 1)) % mod;
            }
            for(int i = 0; i <= m; i++) {
                ll x = c[i];
                x = x * cal(pow(R1, i, mod) * pow(R2, m - i, mod) % mod, n) % mod;
                x = (x % mod + mod) % mod;
                if((m - i) % 2) ans = (ans - x + mod) % mod;
                else ans = (ans + x + mod) % mod;
            }
            ans = ans * pow(S, m, mod) % mod;
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Solution 16: 树的层次遍历
    Solution 15: 树的镜像
    Solution 14: Two Sum
    Solution 13: 链表的倒数第K个节点
    Solution 10: 翻转句子中的单词
    Solution 11: 二叉树中节点的最大距离
    Solution 9: 判断序列是否为BST的后续遍历结果
    Solution 7: 判断两链表是否相交
    估算Baidu和Google的网页索引数量之比
    主元素问题
  • 原文地址:https://www.cnblogs.com/Emcikem/p/13357401.html
Copyright © 2011-2022 走看看