hdu 1588 Gauss Fibonacci(矩阵嵌矩阵)

题目大意:

求出斐波那契中的 第 k*i+b 项的和。

思路分析:

定义斐波那契数列的矩阵

f(n)为斐波那契第n项

F(n) = f(n+1)

f(n)

那么可以知道矩阵

A = 1 1

1  0

使得 F(n) = A * F(n+1)

然后我们化简最后的答案

sum = F(b) +   F(K+b) +  F (2*k +b)....

sum = F(b) +  A^k F(b)    +   A^2k F(b).....

sum = (E+A^k + A^2k.....)*F(b)

那么我们把 矩阵  A^k  定义为矩阵 K。

再递推上面的求和公式。

E E   *   SUM = SUM + E

0 K  E           K

所以构造一个内嵌矩阵的矩阵。

然后求出和乘以F(b)即可。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <iostream>
#define N 2
using namespace std;
typedef long long LL;
LL mod;
struct matrix
{
    LL data[N][N];
    friend matrix operator * (const matrix A,const matrix B)
    {
        matrix res;
        memset(res.data,0,sizeof res.data);
        for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
        for(int k=0;k<N;k++)
        res.data[i][j]+=(A.data[i][k]*B.data[k][j])%mod;
        return res;
    }
    friend matrix operator + (const matrix A,const matrix B)
    {
        matrix res;
        for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
        res.data[i][j]=(A.data[i][j]+B.data[i][j])%mod;
        return res;
    }
    friend matrix operator - (const matrix A,const matrix B)
    {
        matrix res;
        for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
        res.data[i][j]=((A.data[i][j]-B.data[i][j])+mod)%mod;
        return res;
    }
    void print()
    {
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<N;j++)
            printf("%I64d ",data[i][j]);
            puts("");
        }
    }

}E,zero;
struct supermax
{
    matrix ret[N][N];
    friend supermax operator * (supermax A,supermax B)
    {
        supermax res;
        for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
        res.ret[i][j]=zero;

        for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
        for(int k=0;k<N;k++)
        {
            res.ret[i][j]=res.ret[i][j]+(A.ret[i][k]*B.ret[k][j]);
            for(int p=0;p<N;p++)
            for(int q=0;q<N;q++)
            res.ret[i][j].data[p][q]%=mod;
        }
        return res;
    }
};

matrix matmod(matrix origin,LL n)
{
    matrix res=E;

    while(n)
    {
        if(n&1)
        res=res*origin;
        n>>=1;
        origin=origin*origin;
    }
    return res;
}
supermax Do(supermax origin,LL n)
{
    supermax res;
    for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
    res.ret[i][j]=zero;
    for(int i=0;i<N;i++)
    res.ret[i][i]=E;

    while(n)
    {
        if(n&1)
        res=res*origin;
        n>>=1;
        origin=origin*origin;
    }
    return res;
}
int main()
{
    memset(zero.data,0,sizeof zero.data);
    memset(E.data,0,sizeof E.data);
    for(int i=0;i<N;i++)
    E.data[i][i]=1;

    LL k,b,n;
    while(scanf("%I64d%I64d%I64d%I64d",&k,&b,&n,&mod)!=EOF)
    {
        matrix fib;
        fib.data[0][0]=1;
        fib.data[0][1]=1;
        fib.data[1][0]=1;
        fib.data[1][1]=0;

        matrix K=matmod(fib,k);

        supermax o;
        o.ret[0][0]=E;
        o.ret[0][1]=E;
        o.ret[1][0]=zero;
        o.ret[1][1]=K;

        supermax final=Do(o,n);

        matrix tmp=(final.ret[0][0]*zero)+(final.ret[0][1]*E);

        matrix B=matmod(fib,b);
        matrix fibb,fib0;
        fib0.data[0][0]=1;
        fib0.data[1][0]=0;
        fib0.data[0][1]=fib0.data[1][1]=0;
        fibb=B*fib0;

        matrix ans = tmp*fibb;
        printf("%I64d\n",ans.data[1][0]%mod);
    }
    return 0;
}

hdu 1588 Gauss Fibonacci(矩阵嵌矩阵)

时间: 2024-07-30 09:30:26

hdu 1588 Gauss Fibonacci(矩阵嵌矩阵)的相关文章

hdu 1588 Gauss Fibonacci(等比矩阵二分求和)

题目链接:hdu 1588 Gauss Fibonacci 题意: g(i)=k*i+b; f(0)=0f(1)=1f(n)=f(n-1)+f(n-2) (n>=2) 让你求:sum(f(g(i)))for 0<=i<n 题解: S(g(i)) = F(b) + F(b+k) + F(b+2k) + .... + F(b+nk) // 设 A = {1,1,0,1}, (花括号表示矩阵...) // 也就是fib数的变化矩阵,F(x) = (A^x) * {1,0} = F(b) + (

HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和)

HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意: g(i)=k*i+b;i为变量. 给出k,b,n,M,问( f(g(0)) + f(g(1)) + ... + f(g(n)) ) % M的值. 分析: 把斐波那契的矩阵带进去,会发现这个是个等比序列. 推倒: S(g(i)) = F(b) + F(b+k) + F(b+2k) + .... + F(b+nk) // 设 A = {1,1,

矩阵十题【三】 HDU 1588 Gauss Fibonacci

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1588 题目大意:先要知道一组斐波那契数列 i 0 1 2 3 4 5 6 7 f(i) 0 1 1 2 3 5 8 13 下面给你一组数: k,b,n,M 现在知道一组公式g(i)=k*i+b:(i=0,1,2,3...n-1) 让你求出 f(g(i)) 的总和(i=01,2,3,...,n-1),比如给出的数据是2 1 4 100 2*0+1=1   f(1)=1 2*1+1=3   f(3)=2

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

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 "Prob

hdu 1588 Gauss Fibonacci(矩阵快速幂)

Gauss Fibonacci Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2090    Accepted Submission(s): 903 Problem Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r

HDU 1588 Gauss Fibonacci(矩阵快速幂+二分等比序列求和)

HDU 1588 Gauss Fibonacci(矩阵快速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意: g(i)=k*i+b;i为变量. 给出k,b,n,M,问( f(g(0)) + f(g(1)) + ... + f(g(n)) ) % M的值. 分析: 把斐波那契的矩阵带进去,会发现这个是个等比序列. 推倒: S(g(i)) = F(b) + F(b+k) + F(b+2k) + .... + F(b+nk) // 设 A = {1,1,

HDU - 1588 Gauss Fibonacci (矩阵高速幂+二分求等比数列和)

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 "Prob

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

HDU 1588 Gauss Fibonacci 矩阵

首先fib数列可以很随意的推出来矩阵解法,然后这里就是要处理一个关于矩阵的等比数列求和的问题,这里有一个logn的解法,类似与这样 A^0+A^1+A^2+A^3 = A^0 + A^1 + A^2 * (A^0 + A^1) 处理就好了. #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <