51Nod-算法马拉松17(告别奥运)-B-分解

ACM模版

描述

51Nod-算法马拉松17(告别奥运)-B-分解_第1张图片

题解

这道题,着实坑了我半个小时,题目有问题,不够严谨,m%1e9+7应该改为m%(1e9+7),因为一开始没有看出这个问题,所以我愣是看不懂样例,反应过来后也就明了了。

这里问,能否分解,通过实验发现,一定可以分解,所以不用考虑输出no的情况,直接用矩阵乘法就KO.了。

代码

#include 
#include 
#include 

using namespace std;

const long long MAXN = 2;
const long long MOD_ = 1e9 + 7;

struct Matrix
{
    long long line;
    long long a[MAXN + 1][MAXN + 1];
    Matrix()
    {
        line = 2;
        a[0][0] = 1;
        a[0][1] = 2;
        a[1][0] = 1;
        a[1][1] = 1;
    }
};

//  矩阵初始化
Matrix isit(Matrix x, long long c)
{
    for (long long i = 0; i < MAXN; i++)
    {
        for (long long j = 0; j < MAXN; j++)
        {
            x.a[i][j] = c;
        }
    }
    return x;
}

//   矩阵乘法
Matrix Matlab(Matrix x, Matrix s)
{
    Matrix ans;
    ans.line = x.line;
    ans = isit(ans,0);
    for (long long i = 0; i < x.line; i++)
    {
        for (long long j = 0; j < x.line; j++)
        {
            for (long long k = 0; k < s.line; k++)
            {
                ans.a[i][j] = (ans.a[i][j] + x.a[i][k] * s.a[k][j]) % MOD_;
                ans.a[i][j] = (ans.a[i][j] + MOD_) % MOD_;
            }
        }
    }
    return ans;
}

long long FastMatrix(Matrix tmp, long long n)
{
    if (n == 1)
    {
        return 1;
    }
    if (n == 0)
    {
        return 1;
    }
    if (n == 2)
    {
        return 3;
    }
    n--;
    Matrix ans, ch;
    ans.line = 2;
    ans.a[0][0] = 1;
    ans.a[0][1] = 0;
    ans.a[1][0] = 1;
    ans.a[1][1] = 0;
    while (n > 0)
    {
        if (n % 2)
        {
            ans = Matlab(ans, tmp);
        }
        tmp = Matlab(tmp, tmp);
        n /= 2;
    }
    return (ans.a[0][0] + ans.a[0][1]) % MOD_;
}

int main()
{
    Matrix T;
    long long n;
    cin >> n;

    long long x = FastMatrix(T, n);
    cout << (x * x + (n & 1)) % MOD_ << endl;

    return 0;
}

参考

《矩阵相关》

你可能感兴趣的:(数学相关,数论,51Nod-题解集锦)