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;
}
题目链接
别人的递推公式写的很详细,我就不写了,我写下应当注意的事项吧。
看了别人的解题报告 大呼一声模板 就开始码,码了三遍~~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;
}
相关文章推荐
- 2013长沙邀请赛 HDU 4565 So Easy!(矩阵快速幂)
- HDU 4565 So Easy!(思想+矩阵快速幂)——2013 ACM-ICPC长沙赛区全国邀请赛
- hdu 4565 So Easy! /2013 ACM-ICPC 长沙赛区全国邀请赛A题 矩阵乘法
- Hdu 4565 So easy! 2013长沙邀请赛
- HDU 4565 -- So Easy! 数学 && 2013 ACM-ICPC 长沙赛区全国邀请赛 A题
- 【构造共轭函数+矩阵快速幂】HDU 4565 So Easy! (2013 长沙赛区邀请赛)
- HDU 4565 So Easy!(数学+矩阵快速幂)(2013 ACM-ICPC长沙赛区全国邀请赛)
- HDU 4565——So Easy!(矩阵快速幂乘法)
- So Easy! HDU - 4565 矩阵快速幂
- HDU 4565 So Easy! 矩阵快速幂 + 共轭数
- 【矩阵快速幂】HDU_4565_So Easy!
- HDU 4565 So Easy!(矩阵快速幂)
- HDU 4565 So Easy!(矩阵快速幂)
- hdu 4565 So Easy!(矩阵快速幂)
- hdu 4565 So Easy! 矩阵快速幂
- HDU 4565 So Easy!(数学+矩阵快速幂)
- HDU 4565 so easy(矩阵快速幂)
- HDU 4565 So Easy!(矩阵快速幂+数学)
- Hdu 4565 So Easy! 矩阵快速幂+共轭数
- HDU 4565 So Easy!(矩阵快速幂)