51nod1379 索函数

Fib[0]=0,Fib[1]=1,Fib[n]=Fib[n-1]+Fib[n-2] if n>1.

定义索函数Sor(n)=Fib[0]| Fib[1] |Fib[2]|…|Fib[n].

给定整数n,要求计算Sor(n)%1,000,000,007(1e9+7).

Input
第1行:给出一个整数T,表示有T组数据。(1<=T<=10000)
第2行到T+1行,每行一个整数n。(0<=n<=10^10)
Output
对于每个测试用例,输出结果占一行。
Input示例
2
1
2
Output示例1
1
分析:斐波那契数列增长速度非常快,打个表可以发现Sor函数有很多数每一位都是1,找个规律可以发现
,关键就是怎么求位数.直接递推会T掉,矩阵快速幂会非常麻烦,可以用通项公式.,当n足够大的时候,求位数的话取一下log就好了.
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;
const ll mod = 1e9 + 7;

ll T, n, f[110];

ll qpow(ll a, ll b)
{
    ll res = 1;
    while (b)
    {
        if (b & 1)
            res = (res * a) % mod;
        a = (a * a) % mod;
        b >>= 1;
    }
    return res;
}

void init()
{
    f[1] = 1;
    f[2] = 1;
    for (int i = 3; i <= 90; i++)
        f[i] = f[i - 1] + f[i - 2];
}

int main()
{
    scanf("%lld", &T);
    init();
    while (T--)
    {
        scanf("%lld", &n);
        if (n == 0)
            printf("0\n");
        else
        if (n <= 90)
        {
            ll temp = log(f[n]) / log(2.0);
            printf("%lld\n", qpow(2, temp + 1) - 1);
        }
        else
        {
            ll temp = n * log((1 + sqrt(5)) / 2) / log(2.0) - log(sqrt(5)) / log(2.0);
            printf("%lld\n", qpow(2, temp + 1) - 1);
        }
    }

    return 0;
}

 

 

 

 

 

 
posted @ 2017-11-18 16:00  zbtrs  阅读(332)  评论(0编辑  收藏  举报