时间限制 | 2000ms | 空间限制 | 65536KB |
题目:
Fib数列是这样的数列: 1,1,2,3,5,8,13,21,,,,,,. 你能确定它的第n项吗,假设它的第n项为N,你需要编程解决对于另一个输入数M,N % M的值.
输入:
本题只有一组测试数据!! 第一行有用空格隔开的两个整数T,M. (1 <= T,M <= 100000) 以下有T行数据,每行表示Fib数列的第n项. 1 <= n <= 33000000 .
输出:
对于每个n,输出N%M.
样例输入:
3 5
1
2
5
样例输出:
1
1
0
注意空间限制。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll Mod,temp[5][5],n;
void multi(ll x[][5],ll y[][5])
{
memset(temp,0,sizeof(temp));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
temp[i][j]=(temp[i][j]%Mod+(x[i][k]%Mod*y[k][j]%Mod)%Mod)%Mod;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
x[i][j]=temp[i][j]%Mod;
}
void pow(ll x[][5],ll y[][5])
{
x[0][0]=1;x[1][1]=1;
y[0][0]=1;y[0][1]=1;y[1][0]=1;y[1][1]=0;
n=n-2;
while(n>0)
{
if(n&1) multi(x,y);
n/=2;
multi(y,y);
}
}
int main()
{
ll T,m,res[5][5],a[5][5];
scanf("%lld %lld",&T,&m);
while(T--)
{
scanf("%lld",&n);
Mod=m;
if(n==1||n==2) {printf("1
");continue;}
memset(res,0,sizeof(res));
pow(res,a);
printf("%lld
",(res[0][0]+res[1][0])%Mod);
}
}