您的位置:首页 > 其它

CodeForces 450B (矩阵快速幂模板题+负数取模)

2014-10-07 02:42 465 查看
[b]题目链接:[/b]http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=51919

题目大意:斐波那契数列推导。给定前f1,f2,推出指定第N项。注意负数取模的方式:-1%(10^9+7)=10^9+6。

解题思路

首先解出快速幂矩阵。以f3为例。 [f2] * [1 -1] = [f2-f1]=[f3] (幂1次)

[f1] * [1 0] [f2] [f2]

于是fn=[f2] *[1 -1]^(n-2)

[f1] [1 0]

注意一下负数取模。ans=(ans%mod+mod)%mod。

#include "cstdio"
#include "cstring"
#define LL long long
#define mod 1000000007
struct Matrix
{
LL mat[2][2];
Matrix() {memset(mat,0,sizeof(mat));}
Matrix(int a,int b,int c,int d) {mat[0][0]=a;mat[0][1]=b;mat[1][0]=c;mat[1][1]=d;}
};
Matrix operator * (Matrix a,Matrix b)
{
Matrix ret;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
{
ret.mat[i][j]=0;
for(int k=0;k<2;k++)
ret.mat[i][j]+=(a.mat[i][k]*b.mat[k][j])%mod;
}
return ret;
}
Matrix operator ^ (Matrix a,int n)
{
Matrix ret,base=a;
ret.mat[0][0]=ret.mat[1][1]=1;
while(n)
{
if(n&1) ret=ret*base;
base=base*base;
n>>=1;
}
return ret;
}
int main()
{
LL a,b,n;
while(scanf("%I64d%I64d%I64d",&a,&b,&n)!=EOF)
{
if(n==1) printf("%I64d\n",((a%mod)+mod)%mod);
else if(n==2) printf("%I64d\n",((b%mod)+mod)%mod);
else
{
Matrix x(1,-1,1,0),tt;
tt=x^(n-2);
LL ans=a*tt.mat[0][1]+b*tt.mat[0][0];
printf("%I64d\n",((ans%mod)+mod)%mod);
}
}
}


2824556neopenxCodeForces 450BAccepted0 KB78 msGNU C++ 4.61263 B2014-10-07 02:08:58
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: