您的位置:首页 > 其它

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

2013-06-07 01:24 483 查看
解题报告链接

题目链接

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

看了别人的解题报告 大呼一声模板 就开始码,码了三遍~~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 long
int 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法