HDU 4565 矩阵快速幂

来源:互联网 发布:网络平台贷款逾期 编辑:程序博客网 时间:2024/06/08 12:09
//矩阵快速幂模板//用矩阵快速幂实现斐波拉希数的推导//{//1,1//1,0//}/////这个矩阵自乘n次。连续自乘n次的话就没意思了,那还不如直接上Fibonacci递推公式呢。///矩阵的魅力就在于它可以上快速幂。因为矩阵乘法满足结合律么……///注意取模//加M因为有mod负#include <cstdlib>#include <cstring>#include <cstdio>#include <iostream>#define LL __int64using namespace std;LL n,M,a,b,a1,a2;LL tempa,tempb;struct matrix///定义数组{       LL a[2][2];}origin,res;void init(){     origin.a[0][0]=tempa;     origin.a[0][1]=tempb;     origin.a[1][0]=1;     origin.a[1][1]=0;     memset(res.a,0,sizeof(res.a));     res.a[0][0]=res.a[1][1]=1;                  //将res.a初始化为单位矩阵}matrix multiply(matrix x,matrix y){    matrix temp;    memset(temp.a,0,sizeof(temp.a));    for(int i=0;i<2;i++)    {        for(int j=0;j<2;j++)        {            for(int k=0;k<2;k++)            {                temp.a[i][j]+=x.a[i][k]*y.a[k][j];                temp.a[i][j]=(temp.a[i][j]+M)%M;            }        }    }    return temp;}void matmod(LL n){    while(n)    {        if(n&1)        res=multiply(res,origin);        n>>=1;        origin=multiply(origin,origin);    }    LL C1=2*a;    LL C0=2;    //printf("c1 = %d\n",C1);    printf("%I64d\n",((res.a[0][0]*C1+res.a[0][1]*C0)+M)%M);//我忘了我加了M}int  main(){///a0特判。。。。!!!!!!!!!!!!!!!!!!!!!!!!!!!1    while(scanf("%I64d%I64d%I64d%I64d",&a,&b,&n,&M)!=EOF)    {        tempa=2*a;        tempb=b-a*a;        a1=2*a;        a2=2*a*a+2*b;       if(n==2)            cout<<(a2%M)<<endl;        else if(n==1)            cout<<(a1%M)<<endl;        else if(n==0)            cout<<"1"<<endl;        else        {        //cout<<tempa<<" "<<tempb<<endl;            init();            matmod(n-1);        }    }    return 0;}

0 0