zoukankan      html  css  js  c++  java
  • 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
    ", qpow2(t));
        }
    
        return 0;
    }
  • 相关阅读:
    2D ARPG开发之旅(1) 贴图(tilebased)地图的实现(上)贴图修改版
    Microsoft CRM 2011 出现“无法更改域登录名" 错误
    Microsoft CRM 2011 隐藏文件菜单中的”新建活动“菜单
    Microsoft CRM 2011 安装时出现“Could not find GUID for server, Global Catalog not found in forest xxx”的问题
    C#(面向对象)
    delegate(委托)
    ww
    SQL(存储过程,触发器,回滚)
    sss
    EXcel
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7711667.html
Copyright © 2011-2022 走看看