hdu 1588 Gauss Fibonacci (构造矩阵)

来源:互联网 发布:疯狂英语李阳 知乎 编辑:程序博客网 时间:2024/04/29 09:45

题意:

计算这样的斐波那契数的和fb(g(i)) g(i)=k*i+b;n<10000000000

题解:

直接算肯定超时,构造矩阵,用矩阵快速幂解决。参考HERE

公式不好推。


#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>#include<map>#include<set>using namespace std;#define B(x) (1<<(x))typedef long long ll;const int oo=0x3f3f3f3f;const ll OO=1LL<<61;const ll MOD=9973;const int maxn=2;int n,m;struct Matrix{    ll maze[2][2];    friend Matrix operator*(Matrix a,Matrix b)    {        Matrix c;        memset(c.maze,0,sizeof c.maze);        for(int i=0;i<2;i++)            for(int j=0;j<2;j++)                for(int k=0;k<2;k++)                    c.maze[i][j]=(c.maze[i][j]+a.maze[i][k]*b.maze[k][j])%m;        return c;    }    friend Matrix operator^(Matrix a,int k)    {        Matrix c;        for(int i=0;i<2;i++)            for(int j=0;j<2;j++)                c.maze[i][j]=(i==j);        while(k)        {            if(k&1)                c=c*a;            a=a*a;            k>>=1;        }        return c;    }};struct SuperMatrix{    Matrix maze[2][2];    ll Cmaze[4][4];    void In()    {        for(int i=0;i<2;i++)            for(int j=0;j<2;j++)                Cmaze[i][j]=maze[0][0].maze[i][j];        for(int i=0;i<2;i++)            for(int j=2;j<4;j++)                Cmaze[i][j]=maze[0][1].maze[i][j-2];        for(int i=2;i<4;i++)            for(int j=0;j<2;j++)                Cmaze[i][j]=maze[1][0].maze[i-2][j];        for(int i=2;i<4;i++)            for(int j=2;j<4;j++)                Cmaze[i][j]=maze[1][1].maze[i-2][j-2];    }    void Out()    {         for(int i=0;i<2;i++)            for(int j=0;j<2;j++)                maze[0][0].maze[i][j]=Cmaze[i][j];        for(int i=0;i<2;i++)            for(int j=2;j<4;j++)                maze[0][1].maze[i][j-2]=Cmaze[i][j];        for(int i=2;i<4;i++)            for(int j=0;j<2;j++)                maze[1][0].maze[i-2][j]=Cmaze[i][j];        for(int i=2;i<4;i++)            for(int j=2;j<4;j++)                maze[1][1].maze[i-2][j-2]=Cmaze[i][j];    }    friend SuperMatrix operator*(SuperMatrix  a,SuperMatrix b)    {        SuperMatrix c;        memset(c.Cmaze,0,sizeof c.Cmaze);        for(int i=0;i<4;i++)            for(int j=0;j<4;j++)                for(int k=0;k<4;k++)                    c.Cmaze[i][j]=(c.Cmaze[i][j]+a.Cmaze[i][k]*b.Cmaze[k][j])%m;        return c;    }    friend SuperMatrix operator^(SuperMatrix a,int k)    {        SuperMatrix c;        for(int i=0;i<4;i++)            for(int j=0;j<4;j++)                c.Cmaze[i][j]=(i==j);        while(k)        {            if(k&1)                c=c*a;            a=a*a;            k>>=1;        }        return c;    }};int main(){    int k,b;    Matrix Zero,E,A;    memset(Zero.maze,0,sizeof Zero.maze);    E.maze[0][0]=E.maze[1][1]=1;    E.maze[1][0]=E.maze[0][1]=0;    A.maze[0][0]=A.maze[0][1]=A.maze[1][0]=1;    A.maze[1][1]=0;    while(scanf("%d %d %d %d",&k,&b,&n,&m)!=EOF)    {        Matrix Fb=A^b;        Matrix T=A^k;        SuperMatrix MA;        MA.maze[0][0]=T;        MA.maze[0][1]=E;        MA.maze[1][0]=Zero;        MA.maze[1][1]=E;        MA.In();        MA=MA^n;        MA.Out();        T=MA.maze[0][1];        T=Fb*T;        cout<<T.maze[1][0]<<endl;    }    return 0;}



0 0