noip模拟赛 残

分析:这道题有点丧病啊......斐波那契数列本来增长就快,n <= 10^100又套2层,看到题目就让人绝望.不过这种题目还是有套路的.首先求斐波那契数列肯定要用到矩阵快速幂,外层的f可以通过取模来变小,可是里面的f不能直接取模1e9+7.因为余数最多就1e9+7种,所以肯定有一个循环节,打表发现内层f的循环节是2000000016,x的循环节是(1e9+7)*3,在求得时候mod循环节长度就ok了.

关于斐波那契的一些套路要记住:用矩阵快速幂加速、有循环节......

 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const long long mod = 1000000007;
const long long mod2 = mod * 2 + 2;
const long long mod3 = mod2 * 3;

typedef long long ll;

int T, len, shu[210];
char s[210];
ll t;

struct node
{
    ll a[3][3];
    node(){ memset(a, 0, sizeof(a)); }
}x, y;

ll zhuanhuan()
{
    ll res = 0;
    for (int i = 1; i <= len; i++)
        shu[i] = s[i] - '0';
    for (int i = 1; i <= len; i++)
        res = (res * 10 + shu[i]) % mod3;
    return res;
}

node mul1(node x, node y)
{
    node p;
    memset(p.a, 0, sizeof(p.a));
    for (int i = 1; i <= 2; i++)
        for (int j = 1; j <= 2; j++)
            for (int k = 1; k <= 2; k++)
                p.a[i][j] = (p.a[i][j] + x.a[i][k] * y.a[k][j] % mod2) % mod2;
    return p;
}

node mul2(node x, node y)
{
    node p;
    memset(p.a, 0, sizeof(p.a));
    for (int i = 1; i <= 2; i++)
        for (int j = 1; j <= 2; j++)
            for (int k = 1; k <= 2; k++)
                p.a[i][j] = (p.a[i][j] + x.a[i][k] * y.a[k][j] % mod) % mod;
    return p;
}

ll qpow1(ll b)
{
    x.a[1][1] = 0;
    x.a[1][2] = 1;
    y.a[1][1] = 0;
    y.a[1][2] = y.a[2][1] = y.a[2][2] = 1;
    while (b)
    {
        if (b & 1)
            x = mul1(x, y);
        y = mul1(y, y);
        b >>= 1;
    }
    return x.a[1][1];
}

ll qpow2(ll b)
{
    x.a[1][1] = 0;
    x.a[1][2] = 1;
    y.a[1][1] = 0;
    y.a[1][2] = y.a[2][1] = y.a[2][2] = 1;
    while (b)
    {
        if (b & 1)
            x = mul2(x, y);
        y = mul2(y, y);
        b >>= 1;
    }
    return x.a[1][1];
}

int main()
{
    scanf("%d", &T);
    while (T--)
    {
        scanf("%s", s + 1);
        len = strlen(s + 1);
        t = zhuanhuan();
        t = qpow1(t);
        printf("%lld\n", qpow2(t));
    }

    return 0;
}

 

posted @ 2017-10-22 21:06  zbtrs  阅读(166)  评论(0编辑  收藏  举报