Fib数列问题

时间限制 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\n");continue;}
        memset(res,0,sizeof(res));
        pow(res,a);
        printf("%lld\n",(res[0][0]+res[1][0])%Mod);
    }
}

 

posted @ 2018-09-04 21:57  Leozi  阅读(171)  评论(0编辑  收藏  举报