hdu 4565 so easy 线性递推+矩阵乘法+快速幂 2013湖南区域邀请赛

来源:互联网 发布:龙虎榜数据分析软件2.3 编辑:程序博客网 时间:2024/05/01 19:25

解题报告链接

题目链接

别人的递推公式写的很详细,我就不写了,我写下应当注意的事项吧。

看了别人的解题报告 大呼一声模板 就开始码,码了三遍~~wa了无数次,还有就是栈溢出等等  我就郁闷了,这个模板是略有不同的。

(1)存在负数的情况  以往做的题都 矩阵中都是正数 而现在出现的负数的情况 对于编译器来讲 -9%2=-1  这个是需要注意的。 最后的结果可能也为负数,所以要加上模的数。

(2)矩阵中的数据类型最好全是long long  带进矩阵中的数最好全是模过的数。

(3)注意矩阵乘法不满足交换律,一定要注意乘法的方向

 (4)杭电中输出不要用%lld 要用%I64d   linux是输出lld ,windows 是I64d 。所以杭电用的是盗版windows server。

下面是代码:

#include<stdio.h>#include<string.h>#include<iostream>#include<math.h>using namespace std;#define ll long longint mm;struct Matrix {    int n,m;    ll a[5][5];    void clear(){        n=0;m=0;        memset(a,0,sizeof(a));    }    Matrix operator *(const Matrix b)const{  //重载乘法运算符        Matrix tmp;        tmp.clear();        tmp.n=n;        tmp.m=b.m;        for(int i=1;i<=tmp.n;i++)            for(int j=1;j<=tmp.m;j++)                for(int k=1;k<=m;k++){                   tmp.a[i][j]+=a[i][k]*b.a[k][j];                   tmp.a[i][j]=tmp.a[i][j]%mm;                }            return tmp;    }}base,ori,ans;Matrix fun(int n){    //快速幂    if(n==1)return base;    Matrix tt=fun(n/2);    tt=tt*tt;    if(n%2==1)tt=tt*base;    return tt;}int main(){    ll a,b,n;    ll ansOne,ansTwo;    while(scanf("%I64d%I64d%I64d%d",&a,&b,&n,&mm)!=EOF){          a=a%mm;          ansOne=2*a%mm;          ansTwo=2*(a*a+b)%mm;          if(n==0){printf("1\n");continue;}          if(n==1){printf("%lld\n",ansOne);continue;}          if(n==2){printf("%lld\n",ansTwo);continue;}          ori.n=2;ori.m=1;ori.a[1][1]=ansTwo;ori.a[2][1]=ansOne;          base.n=2;base.m=2;base.a[1][1]=ansOne;base.a[1][2]=b-a*a;base.a[2][1]=1;base.a[2][2]=0;          Matrix ans=fun(n-2);          ans=ans*ori;          if(ans.a[1][1]<0)ans.a[1][1]=(ans.a[1][1]+mm)%mm;          printf("%I64d\n",ans.a[1][1]);    }    return 0;}


原创粉丝点击