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...+A^(n-1)k)

所以A^b与A^k可以用矩阵快速幂求解

之后可以设B = A^k

所以式子可以转化为sum = A^b(1 + B + B^2..+ B^(n - 1))

sum就可以使用等比数列二分求和来解决了。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

//typedef long long ll;
typedef __int64 ll;

const int N = 2;

struct mat{
    ll s[N][N];
    mat(ll a = 0, ll b = 0, ll c = 0, ll d = 0) {
        s[0][0] = a;
        s[0][1] = b;
        s[1][0] = c;
        s[1][1] = d;
    }
    mat operator * (const mat& c) {
        mat ans;
        memset(ans.s, 0, sizeof(ans.s));
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                ans.s[i][j] = (s[i][0] * c.s[0][j] + s[i][1] * c.s[1][j]);
        return ans;
    }
    mat operator % (int mod) {
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                s[i][j] %= mod;
        return *this;
    }
    mat operator + (const mat& c) {
        mat ans;
        memset(ans.s, 0, sizeof(ans.s));
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                ans.s[i][j] = s[i][j] + c.s[i][j];
        return ans;
    }
    void put() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++)
                printf("%I64d ", s[i][j]);
            printf("\n");
        }
    }
}c(1, 1, 1, 0), tmp(1, 0, 0, 1);

ll k, b, n, M;

mat pow_mod(int n, mat c) {
    if (n == 0)
        return tmp;
    if (n == 1)
        return c;
    mat a = pow_mod(n / 2, c);
    mat ans = a * a % M;
    if (n % 2)
        ans = ans * c % M;
    return ans;
}

mat sum(int n, mat a) {
    if (n == 1)
        return a;
    if (n & 1)
        return (pow_mod(n, a) + sum(n - 1, a)) % M;
    else
        return (((pow_mod(n / 2, a) + tmp) % M) * sum(n / 2, a) % M);
}

int main() {
    while (scanf("%I64d%I64d%I64d%I64d", &k, &b, &n, &M) != EOF) {
        mat A = pow_mod(b, c);
        mat B = pow_mod(k, c);
        mat C = sum(n - 1, B) + tmp;
        C = C * A;
        printf("%I64d\n", C.s[0][1] % M);
    }
    return 0;
}
时间: 2024-10-26 04:12:00

HDU1588-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

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

POJ 3233 Matrix Power Series 【经典矩阵快速幂+二分】

任意门:http://poj.org/problem?id=3233 Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 28619   Accepted: 11646 Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + - + Ak. Input The

$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

POJ 3070 Fibonacci(矩阵快速幂)

Description 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 the Fibonacci sequence is

HDU 3306 Another kind of Fibonacci(矩阵快速幂)

题目地址:HDU 3306 没什么智商的题目,只要把构造矩阵硬算出来就行. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <m