hdu 2604 矩阵快速幂

来源:互联网 发布:网络大电影方案 编辑:程序博客网 时间:2024/05/22 06:32
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<queue>#include<stack>#include<set>#include<map>#include<algorithm>using namespace std;typedef long long ll;#define Matr 10struct mat{    ll a[Matr][Matr],size;    mat()    {        size=0;        memset(a,0,sizeof(a));    }};mat multi(mat m1,mat m2,int mod){    mat ans=mat();    ans.size=m1.size;    for(int i=1;i<=m1.size;i++)        for(int j=1;j<=m2.size;j++)            if(m1.a[i][j])//稀疏矩阵优化                for(int k=1;k<=m1.size;k++)                    ans.a[i][k]=(ans.a[i][k]+m1.a[i][j]*m2.a[j][k])%mod;    return ans;}void print(mat m)//输出矩阵信息,debug用{    int i,j;    printf("%d\n",m.size);    for(i=1;i<=m.size;i++)    {        for(j=1;j<=m.size;j++)            printf("%d ",m.a[i][j]);        printf("\n");    }}mat quickmulti(mat m,int n,int mod)//二分快速幂{    mat ans=mat();    int i;    for(i=1;i<=m.size;i++)ans.a[i][i]=1;    ans.size=m.size;    while(n)    {        if(n&1)ans=multi(m,ans,mod);        m=multi(m,m,mod);        n>>=1;    }    return ans;}/*ans^=n ->mat ans=mat();ans.size=Size;初始化ans矩阵ans=quickmulti(ans,n,mod);*/int n,m;int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        if(n==0)            printf("%d\n",1%m);        else if(n==1)            printf("%d\n",2%m);        else if(n==2)            printf("%d\n",4%m);        else        {            mat ans=mat();            ans.size=2;            ans.a[1][1]=ans.a[1][2]=ans.a[2][1]=1;            ans=quickmulti(ans,(n+1)/2-1,m);            if(n&1)            {                int res;                res=(ans.a[1][1]*2%m+ans.a[2][1])%m;                res=(res*(ans.a[1][2]*2%m+ans.a[2][2])%m)%m;                printf("%d\n",res);            }            else            {                int res;                res=(ans.a[1][1]*2%m+ans.a[2][1])%m;                res=(res*res)%m;                printf("%d\n",res);            }        }    }    return 0;}

0 0
原创粉丝点击