zoukankan      html  css  js  c++  java
  • $HDU 2020$ 多校第一场

    (6755 Fibonacci Sum)

    题意

    给定 (C, N, K)

    规定 (F_{0} = 0, F_{1} = 1, F_{n} = F_{n - 1} + F_{n - 2})

    计算

    [F_{0}^k + F_{C}^k + F_{2C}^k + ... + F_{CN}^k ]

    (1leq N, Cleq 1e18, 1leq Kleq 1e5)

    题解

    由斐波那契通项公式

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

    不妨设

    [a = frac{1 + sqrt{5}}{2}, b = frac{1 - sqrt{5}}{2} ]

    于是得到

    [sum_{i = 0}^{N}F_{ic}^k = sum_{i = 0}^{N}(frac{1}{sqrt{5}})^{k}(a^{ic} - b^{ic})^{k} ]

    由二项式定理

    [(a + b)^n = sum_{i = 0}^{n}C_{n}^{i}a^{n - i}b^{i} ]

    展开得到

    [sum_{i = 0}^{N}F_{ic}^k = (frac{1}{sqrt{5}})^{k}sum_{i = 0}^{N}sum_{j = 0}^{k}C_{k}^{j}(a^{ic})^{k - j}(-b^{ic})^{j} ]

    交换求和顺序,整理得到

    [sum_{i = 0}^{N}F_{ic}^k = (frac{1}{sqrt{5}})^{k}sum_{j = 0}^{k}C_{k}^{j}(-1)^{j}sum_{i = 0}^{N}(a^{c(k - j)}cdot b^{cj})^{i} ]

    发现第二个循环内部是一个等比数列,设

    [q = a^{c(k - j)}cdot b^{cj} = left[a^{k - j}b^{j} ight]^{c} ]

    由求和公式,化简第二层循环(特判 (q = 1)

    [sum_{i = 0}^{N}(a^{c(k - j)}cdot b^{cj})^{i} = frac{1 - q^{N + 1}}{1 - q} ]

    代入原式得到

    [sum_{i = 0}^{N}F_{ic}^k = (frac{1}{sqrt{5}})^{k}sum_{j = 0}^{k}C_{k}^{j}(-1)^{j}(frac{q^{N + 1} - 1}{q - 1}) ]

    下面考虑优化计算

    [q_{j} = left[a^{k - j}b^{j} ight]^{c}, qn_{j} = left[a^{k - j}b^{j} ight]^{c cdot (N + 1)} ]

    [q_{j + 1} = left[a^{k - j - 1}b^{j + 1} ight]^{c}, qn_{j + 1} = left[a^{k - j - 1}b^{j + 1} ight]^{c cdot (N + 1)} ]

    [q_{j + 1} = frac{q_{j}}{a^{c}}cdot b^{c}, qn_{j + 1} = frac{qn_{j}}{a^{ccdot (N + 1)}}cdot b^{ccdot (N + 1)} ]

    [K_{1} = frac{b^c}{a^c}, K_{2} = frac{b^{ccdot (N + 1)}}{a^{ccdot (N + 1)}} ]

    (q, qn) 可以线性递推

    [q_{j + 1} = q_{j}cdot K_{1}, qn_{j + 1} = qn_{j}cdot K_{2} ]

    模意义下的指数运算要用欧拉降幂,这是一个 (wa)

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int, int>
    #define pb push_back
    #define dbg(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " 
    "[i == r])
    typedef long long LL;
    typedef unsigned long long ULL;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL MOD = 1e9 + 9;
    const int inf = 0x3f3f3f3f;
    const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
    const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
    const int MAXN = 1e5 + 7;
    const double PI = acos(-1);
    const double EPS = 1e-6;
    using namespace std;
    
    LL qpow(LL a, LL b)
    {
        b %= MOD - 1;
        if(!a) return 0;
        LL ans = 1;
        while(b) {
            if(b & 1) ans *= a, ans %= MOD;
            a *= a, a %= MOD, b >>= 1;
        }
        return ans;
    }
    LL getInv(LL x) {return qpow(x, MOD - 2);}
    LL Add(LL a, LL b) {a = (a % MOD + MOD) % MOD; b = (b % MOD + MOD) % MOD; return (a + b) % MOD;}
    LL Sub(LL a, LL b) {a = (a % MOD + MOD) % MOD; b = (b % MOD + MOD) % MOD; return (a - b + MOD) % MOD;}
    LL Mul(LL a, LL b) {a = (a % MOD + MOD) % MOD; b = (b % MOD + MOD) % MOD; return a * b % MOD;}
    LL Div(LL a, LL b) {a = (a % MOD + MOD) % MOD; b = (b % MOD + MOD) % MOD; return b * getInv(a) % MOD;}
    
    int t, K;
    LL N, C, fac[MAXN], inv_fac[MAXN], q[MAXN], qn[MAXN];
    const LL A = 383008016, B = getInv(2), INVA = getInv(A);
    const LL a = Mul(Add(1, A), B), b = Mul(Sub(1, A), B);
    
    void ini()
    {
        fac[0] = 1;
        for(int i = 1; i < MAXN; ++i) fac[i] = Mul(fac[i - 1], i);
        inv_fac[MAXN - 1] = getInv(fac[MAXN - 1]);
        for(int i = MAXN - 2; i >= 0; --i) inv_fac[i] = Mul(inv_fac[i + 1], i + 1);
    }
    LL getC(int k, int i)
    {
        return Mul(fac[k], Mul(inv_fac[i], inv_fac[k - i]));
    }
    LL getGeoSum(LL Q, LL Qn)
    {
        LL res = Div(Sub(Q, 1), Sub(Qn, 1));
        return res;
    }
    int main()
    {
        ini();
        scanf("%d", &t);
        while(t--) {
            scanf("%lld %lld %d", &N, &C, &K);
            LL ans = 0;
            LL K1 = Div(qpow(a, C), qpow(b, C));
            LL K2 = Div(qpow(qpow(a, C), N + 1), qpow(qpow(b, C), N + 1));
            q[0] = qpow(qpow(a, K), C);
            qn[0] = qpow(q[0], N + 1);
            for(int j = 1; j <= K; ++j) {
                q[j] = Mul(q[j - 1], K1);
                qn[j] = Mul(qn[j - 1], K2);
            }
            for(int j = 0; j <= K; ++j) {
                LL Q = q[j], Qn = qn[j];
                LL Com = getC(K, j);
                LL flag = j % 2 ? -1 : 1;
                LL sum1 = Mul(Com, flag), sum2 = 0;
                if(Q == 1) sum2 = Mul(sum1, Add(N, 1));
                else sum2 = Mul(sum1, getGeoSum(Q, Qn));
                ans = Add(ans, sum2);
            }
            LL co = qpow(INVA, K);
            ans = Mul(ans, co);
            printf("%lld
    ", ans);
        }
        return 0;
    }
    /*
    3
    5 1 1
    2 1 2
    948667308466040306 674466112463401647 84933
    */
    
  • 相关阅读:
    python基础-函数递归
    JS中变量、作用域的本质,定义及使用方法
    JS数据类型和堆栈+变量比较和值的复制+参数传递和类型检测
    宣传页项目开发(三)
    宣传页项目开发(二)
    宣传页项目实战
    CSS Sprite雪碧图应用
    PS切图工具
    根据js轮播图原理写出合理的结构与样式、并实现js交互效果
    JS事件流、DOM事件流、IE事件处理、跨浏览器事件处理、事件对象与类型
  • 原文地址:https://www.cnblogs.com/ChenyangXu/p/13362642.html
Copyright © 2011-2022 走看看