Hdoj 1588 Gauss Fibonacci 【矩阵快速幂】

Gauss Fibonacci

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2584 Accepted Submission(s): 1078

Problem Description

Without expecting, Angel replied quickly.She says: “I’v heard that you’r a very clever boy. So if you wanna me be your GF, you should solve the problem called GF~. ”

How good an opportunity that Gardon can not give up! The “Problem GF” told by Angel is actually “Gauss Fibonacci”.

As we know ,Gauss is the famous mathematician who worked out the sum from 1 to 100 very quickly, and Fibonacci is the crazy man who invented some numbers.

Arithmetic progression:

g(i)=k*i+b;

We assume k and b are both non-nagetive integers.

Fibonacci Numbers:

f(0)=0

f(1)=1

f(n)=f(n-1)+f(n-2) (n>=2)

The Gauss Fibonacci problem is described as follows:

Given k,b,n ,calculate the sum of every f(g(i)) for 0<=i

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define LL __int64

struct node{
    LL num[3][3];
};
node e, a;
LL n, m, k, b;

node mul(node aa, node bb){
    node c;
    for(int i = 1; i < 3; ++i){
        for(int j = 1; j < 3; ++j){
            c.num[i][j] = 0;
            for(int k = 1; k < 3; ++k){
                c.num[i][j] = (c.num[i][j]+aa.num[i][k]*bb.num[k][j])%m;
            }
        }
    }
    return c;
}

node fa(node a, LL n){
    node b = e;
    while(n){
        if(n&1) b = mul(a, b);
        n >>= 1;
        a = mul(a, a);
    }
    return b;
}

node add(node aa, node bb){
    node c;
    for(int i = 1; i < 3; ++i){
        for(int j = 1; j < 3; ++j){
            c.num[i][j] = (aa.num[i][j]+bb.num[i][j])%m;
        }
    }
    return c;
}

node dg(node p, LL k){  //这里很巧
    if(k == 1) return p;
    else if(k&1) return add(dg(p, k-1), fa(p, k)); //这里就是A^(K-1)+A^k
    else return mul(dg(p, k>>1), add(fa(p, k>>1), e));//这里就是 A^k+A^(k>>1);
}

int main(){
    e.num[1][1] = e.num[2][2] = 1;
    e.num[1][2] = e.num[2][1] = 0;
    a.num[1][1] = a.num[1][2] = a.num[2][1] = 1; a.num[2][2] = 0;
    while(cin >> k >> b >> n >> m){
        node ak = fa(a, k);
        node ab = fa(a, b);
        node ans = dg(ak, n-1);
        ans = add(e, ans);
        ans = mul(ab, ans);
        cout << ans.num[1][2]<< endl;
    }
    return 0;
}
时间: 2024-10-03 13:09:47

Hdoj 1588 Gauss Fibonacci 【矩阵快速幂】的相关文章

HDU 1588 Gauss Fibonacci(矩阵快速幂)

题目地址:HDU 1588 用于构造斐波那契的矩阵为 1,1 1,0 设这个矩阵为A. sum=f(b)+f(k+b)+f(2*k+b)+f(3*k+b)+........+f((n-1)*k+b) <=>sum=A^b+A^(k+b)+A^(2*k+b)+A^(3*k+b)+........+A^((n-1)*k+b) <=>sum=A^b+A^b*(A^k+A^2*k+A^3*k+.......+A^((n-1)*k))(1) 设矩阵B为A^k; 那么(1)式为 sum=A^b

poj 3070 Fibonacci (矩阵快速幂求斐波那契数列的第n项)

题意就是用矩阵乘法来求斐波那契数列的第n项的后四位数.如果后四位全为0,则输出0,否则 输出后四位去掉前导0,也...就...是...说...输出Fn%10000. 题目说的如此清楚..我居然还在%和/来找后四位还判断是不是全为0还输出时判断是否为0然后 去掉前导0.o(╯□╰)o 还有矩阵快速幂的幂是0时要特判. P.S:今天下午就想好今天学一下矩阵乘法方面的知识,这题是我的第一道正式接触矩阵乘法的题,欧耶! #include<cstdio> #include<iostream>

poj 3070 Fibonacci 矩阵快速幂

题目链接:http://poj.org/problem?id=3070 In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, … An alternative formula for t

HDU1588-Gauss Fibonacci(矩阵快速幂+等比数列二分求和)

题目链接 题意:g(x) = k * x + b.f(x) 为Fibonacci数列.求f(g(x)),从x = 1到n的数字之和sum,并对m取模. 思路: 设A = |(1, 1),(1, 0)| sum = f(b) + f(k + b) + f(2k + b)...+f((n-1)k + b) (f(x) 为Fibonacci数列) sum = A^b + A^(k + b) + A^(2k + b)...+ A^((n-1)k + b) sum = A^b(1 + A^k + A^2k

poj 3070 Fibonacci (矩阵快速幂乘/模板)

题意:给你一个n,输出Fibonacci (n)%10000的结果 思路:裸矩阵快速幂乘,直接套模板 代码: #include <cstdio> #include <cstring> #include <iostream> using namespace std; typedef long long ll; const int N=2,M=2,P=2; const int MOD=10000; struct Matrix { ll m[N][N]; }; Matrix

UVA10229Modular Fibonacci(矩阵快速幂)

题目链接 题目大意:给你i和m,求Mi, Mi = (F(i - 1) + F(i - 2)) % 2^m; 解题思路:因为Mi = (F(i - 1) % 2^m + F(i - 2)% 2^m) % 2^m = (M(i - 1) + M(i - 2)) % 2^m.类似于求fibonacci数加上取模,只是n很大,所以要用矩阵快速幂快速求解.参考 代码: #include <cstdio> #include <cstring> typedef long long ll; co

HDOJ 2294 - Pendant(DP+矩阵快速幂)

题目链接 题意:有个高富帅,要送个很装逼的吊坠给他女朋友.他有k种珠子,然后要串成一个珠子个数小于等于n 的链子(k种珠子都必须要用到).输入n和k,输出他可以做出多少种不一样的项链. 思路:可以想到递推式f(x, y) = f(x – 1, y) * y + f(x – 1, y – 1) * (k – y + 1)(表示x个珠子用了y种类型),因为n过大,无法直接求出来,所以要使用矩阵快速幂. GG队友的思路 代码: #include <iostream> #include <cst

hdoj 4062 Queuing 【矩阵快速幂优化递推公式】

Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3609    Accepted Submission(s): 1629 Problem Description Queues and Priority Queues are data structures which are known to most computer

$loj$10222 佳佳的$Fibonacci$ 矩阵快速幂

正解:矩阵快速幂 解题报告: 我永远喜欢loj! 一看到这个就应该能想到矩阵快速幂? 然后就考虑转移式,发现好像直接想不好想,,,主要的问题在于这个*$i$,就很不好搞$QAQ$ 其实不难想到,$\sum_{i=1}^{n}a_i\cdot(n-i)$这样一个式子是可以在矩阵快速幂中推出来的(类似这个形式的都可,,,就随着编号递增系数递减这样子$QwQ$ 具体来说就是表示成$\sum_{i=1}^{n}\sum_{j=1}^{i}a_j$,就欧克辣(具体实现后面港,,, 但是问题在于,它是$\s