WikiOI 1732/1250 Fibonacci数列
题目描述Description
在“1250 Fibonacci数列”中,我们求出了第n个Fibonacci数列的值。但是1250中,n<=109。现在,你的任务仍然是求出第n个Fibonacci数列的值,但是注意:n为整数,且1 <= n <= 100000000000000
输入描述Input Description
输入有多组数据,每组数据占一行,为一个整数n(1 <= n <= 100000000000000)
输出描述Output Description
输出若干行。每行输出第(对应的输入的)n个Fibonacci数(考虑到数会很大,mod 1000000007)
样例输入Sample Input
3
4
5
样例输出Sample Output
2
3
5
数据范围及提示Data Size & Hint
1 <= n <= 100000000000000
这一题是1250的加强版,就合在一起写了
不过注意一点,1250是从0下标开始,这一题1732是从1下标开始
第一次写矩阵乘法,1250就1A了
然后就高高兴兴改了输入,交1732,结果WA了,还只有10分!!!改了好久20分,又改,又改,80分,终于A了
中间遇到的错误点
1.读入的 n 是 long long
2.快速幂x^y,其中 y 为 long long
3.矩阵乘法每次都要去mod
测评情况(WikiOI)
C++ AC Code(1732)
/*http://blog.csdn.net/jiangzh7
By Jiangzh*/
#include<cstdio>
#include<cstring>
const int mod=1000000007;
long long n;
struct Matrix{
long long c[5][5];
Matrix operator * (Matrix b)
{
Matrix res;
res.c[1][1]=c[1][1]*b.c[1][1]%mod+c[1][2]*b.c[2][1]%mod;
res.c[1][2]=c[1][1]*b.c[1][2]%mod+c[1][2]*b.c[2][2]%mod;
res.c[2][1]=c[2][1]*b.c[1][1]%mod+c[2][2]*b.c[2][1]%mod;
res.c[2][2]=c[2][1]*b.c[1][2]%mod+c[2][2]*b.c[2][2]%mod;
return res;
}
Matrix getans(Matrix b)
{
Matrix res;
res.c[1][1]=c[1][1]*b.c[1][1]%mod+c[1][2]*b.c[2][1]%mod;
res.c[2][1]=c[2][1]*b.c[1][1]%mod+c[2][2]*b.c[2][1]%mod;
return res;
}
Matrix operator % (int mod)
{
c[1][1]%=mod;c[1][2]%=mod;
c[2][1]%=mod;c[2][2]%=mod;
return *this;
}
};
Matrix mul(Matrix x,long long y,int mod)
{
if(y==1) return x;
if(y&1) return mul(x*x%mod,y/2,mod)%mod*x;
else return mul(x*x%mod,y/2,mod)%mod;
}
long long calc()
{
n--;
if(n==1||n==0) return 1;
Matrix a;
a.c[1][1]=a.c[1][2]=a.c[2][1]=1;
a.c[2][2]=0;
a=mul(a,n-1,mod);
Matrix b; b.c[1][1]=b.c[2][1]=1;
a=a.getans(b);
return a.c[1][1]%mod;
}
int main()
{
freopen("1732.in","r",stdin);
freopen("1732.out","w",stdout);
while(scanf("%lld",&n)==1)
printf("%lld\n",calc());
return 0;
}
C++ AC Code(1250)
/*http://blog.csdn.net/jiangzh7
By Jiangzh*/
#include<cstdio>
#include<cstring>
int n,mod;
struct Matrix{
long long c[5][5];
Matrix operator * (Matrix b)
{
Matrix res;
res.c[1][1]=c[1][1]*b.c[1][1]+c[1][2]*b.c[2][1];
res.c[1][2]=c[1][1]*b.c[1][2]+c[1][2]*b.c[2][2];
res.c[2][1]=c[2][1]*b.c[1][1]+c[2][2]*b.c[2][1];
res.c[2][2]=c[2][1]*b.c[1][2]+c[2][2]*b.c[2][2];
return res;
}
Matrix getans(Matrix b)
{
Matrix res;
res.c[1][1]=c[1][1]*b.c[1][1]+c[1][2]*b.c[2][1];
res.c[2][1]=c[2][1]*b.c[1][1]+c[2][2]*b.c[2][1];
return res;
}
Matrix operator % (int mod)
{
c[1][1]%=mod;c[1][2]%=mod;
c[2][1]%=mod;c[2][2]%=mod;
return *this;
}
};
Matrix mul(Matrix x,int y,int mod)
{
if(y==1) return x;
if(y&1) return mul(x*x%mod,y/2,mod)%mod*x;
else return mul(x*x%mod,y/2,mod)%mod;
}
long long calc()
{
if(n==1||n==0) return 1;
Matrix a;
a.c[1][1]=a.c[1][2]=a.c[2][1]=1;
a.c[2][2]=0;
a=mul(a,n-1,mod);
Matrix b; b.c[1][1]=b.c[2][1]=1;
a=a.getans(b);
return a.c[1][1]%mod;
}
int main()
{
freopen("1250.in","r",stdin);
freopen("1250.out","w",stdout);
int T; scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&mod);
printf("%lld\n",calc());
}
return 0;
}