zoukankan      html  css  js  c++  java
  • HDU-1588 Gauss Fibonacci

    题目大意:

    有两个函数,g[i] = k * i + b,另外一个函数f[i] = f[i-1] + f[i-2],问你从0到n-1的f(g[i])的和。

    解题思路:

    斐波那契数列有种递推的思路是:

    {f[i+1], f[i]; f[i], f[i-1]} = A ^ i

    其中A = {1, 1; 1, 0}

    这样的话,我们可以利用这样的特性,另f[i] = A^i,这样可以把这个问题利用矩阵的特性解出来。

    也就是 sigma(0, n-1) f(g[i]) = A^b + A^(k + b) + A^(2k + b) + ... + A^((n-1)k + b)

    这个地方就可以利用二分求等比数列的和,这个可以参考poj1845的一种解法。推荐博客

    然后就是一种类比了。最后只需要输出2*2矩阵的非主对角线元素的任意一个就可以。

    代码:

    #include <map>
    #include <set>
    #include <queue>
    #include <stack>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    
    #define mp make_pair
    #define pb push_back
    #define lson (rt << 1)
    #define rson (rt << 1 | 1)
    #define fun(x) ((x) >= 0 ? (x) : -(x))
    
    typedef long long LL;
    typedef pair<int, int> pi;
    typedef struct node{
        LL r0, r1, r2, r3;
        node(LL a = 0, LL b = 0, LL c = 0, LL d = 0) {
            r0 = a; r1 = b;
            r2 = c; r3 = d;
        }
    }Matrix;
    
    const Matrix one = Matrix(1, 0, 0, 1);
    const Matrix fib = Matrix(1, 1, 1, 0);
    
    LL mod;
    Matrix ab;
    
    Matrix fastMatrix(Matrix x, LL n) {
        LL t11, t12, t21, t22;
        Matrix m1 = x, m2 = one;
    
        while (n) {
            if (n & 1) {
                t11 = ((m2.r0 * m1.r0) % mod + (m2.r1 * m1.r2) % mod) % mod;
                t12 = ((m2.r0 * m1.r1) % mod + (m2.r1 * m1.r3) % mod) % mod;
                t21 = ((m2.r2 * m1.r0) % mod + (m2.r3 * m1.r2) % mod) % mod;
                t22 = ((m2.r2 * m1.r1) % mod + (m2.r3 * m1.r3) % mod) % mod;
    
                m2 = Matrix(t11, t12, t21, t22);
            }
    
            n >>= 1;
            t11 = ((m1.r0 * m1.r0) % mod + (m1.r1 * m1.r2) % mod) % mod;
            t12 = ((m1.r0 * m1.r1) % mod + (m1.r1 * m1.r3) % mod) % mod;
            t21 = ((m1.r2 * m1.r0) % mod + (m1.r3 * m1.r2) % mod) % mod;
            t22 = ((m1.r2 * m1.r1) % mod + (m1.r3 * m1.r3) % mod) % mod;
    
            m1 = Matrix(t11, t12, t21, t22);
        }
        return m2;
    }
    Matrix operator + (Matrix a, Matrix b){
        Matrix ans;
        ans.r0 = (a.r0 + b.r0) % mod;
        ans.r1 = (a.r1 + b.r1) % mod;
        ans.r2 = (a.r2 + b.r2) % mod;
        ans.r3 = (a.r3 + b.r3) % mod;
        return ans;
    }
    Matrix operator * (Matrix a, Matrix b){
        Matrix ans;
        ans.r0 = ((a.r0 * b.r0) % mod + (a.r1 * b.r2) % mod) % mod;
        ans.r1 = ((a.r0 * b.r1) % mod + (a.r1 * b.r3) % mod) % mod;
        ans.r2 = ((a.r2 * b.r0) % mod + (a.r3 * b.r2) % mod) % mod;
        ans.r3 = ((a.r2 * b.r1) % mod + (a.r3 * b.r3) % mod) % mod;
        return ans;
    }
    Matrix CalAns(Matrix x, LL n, LL k) {
        if(n == 0) return one;
        if(n == 1) {
            Matrix y = fastMatrix(x, k);
            ++y.r0; ++y.r3;
            return y;
        }
    
        Matrix res = one;
        if(n % 2 == 1){
            res = res + fastMatrix(x, (n / 2 + 1) * k);
            res = res * CalAns(x, n / 2, k);
        }else{
            res = res + fastMatrix(x, ((n - 1) / 2 + 1) * k);
            res = res * CalAns(x, (n - 1) / 2, k);
            res = res + fastMatrix(x, n * k);
        }
        return res;
    }
    int main(){
        ios::sync_with_stdio(false); cin.tie(0);
        LL k, b, n, m;
        while (cin >> k >> b >> n >> m) {
            mod = m;
            ab = fastMatrix(fib, b);
            Matrix ans = CalAns(fib, n - 1, k);
            ans = ans * ab;
            cout << ans.r1 << endl;
        }
        return 0;
    }



  • 相关阅读:
    已解决: 已引发: "无法加载 DLL“opencv_core2410”: 找不到指定的模块。
    Xcode 设置图片全屏显示
    独创轻松实现拖拽,改变层布局
    WCF Odata 开放数据协议应用
    MVC中,加入的一个aspx页面用到AspNetPager控件处理办法
    关于 HRESULT:0x80070
    Springboot文件上传大小设置
    Jquery Validate 表单验证使用
    Quartz任务调度框架使用
    js中常见命令
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179342.html
Copyright © 2011-2022 走看看