ACMer中的渣渣

梦想还是要有的,万一实现了呢。

51nod - 1573 分解 - 矩阵快速幂

51nod 算法马拉松17(告别奥运)B 分解 51nod 算法马拉松17(告别奥运)B 分解
题意 :给出一个n,问(1+2)n 能否拆成m+m1 的形式,如果能,输出m,否则输出 no。

想法
观察(1+2)n,它总能写成a+b2的形式,如果a2n=m2b2n=m1 或者a2n=m12b2n=m,那就可以了。 于是我们设(1+2)n=an+bn2,不难找到(anbn)=(a1b1)(1211)n1

#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
const int mod = 1e9 + 7;
int t = 2;
struct mat
{
    long long v[maxn][maxn];
    int n;
    void clear()
    {
        n = t;
        memset(v, 0, sizeof(v));
    }
    void unit()
    {
        clear();
        for(int i=0; i<n; i++)
            v[i][i] = 1;
    }
    void fro()
    {
        clear();
        v[0][1] = v[1][0] = v[1][1] = 1;
    }
    void print()
    {
        for(int i=0; i<n; i++)
        {
            cout << v[i][0];
            for(int j=1; j<n; j++)
                cout << " " << v[i][j];
            cout << endl;
        }
    }

};
mat operator * (const mat a, const mat b)
{
    mat res;
    res.clear();
    for(int i=0; i<t; i++)
    {
        for(int j=0; j<t; j++)
        {
            for(int k=0; k<t; k++)
            {
                res.v[i][j] = (res.v[i][j] + a.v[i][k] * b.v[k][j]) % mod;
            }
        }
    }
    return res;
}
mat operator ^ (mat a, long long b)
{
    mat r , base = a;
    r.unit();
    while(b)
    {
        if(b&1)
            r = r * base;
        base = base * base;
        b >>= 1;
    }
    return r;
}
int main()
{
    long long m;
    mat a;
    a.clear();
    a.v[0][0] = 1, a.v[0][1] = 1;
    a.v[1][0] = 2, a.v[1][1] = 1;
    cin >> m;
    if(m == 0) {
        cout << 1 << endl; return 0;
    } else if(m == 1) {
        cout << 2 << endl; return 0;
    }
    a = (a^(m-1));
    long long t = a.v[0][0] + a.v[1][0];
    long long s = a.v[0][1] + a.v[1][1];
    long long tm = (t % mod) * (t % mod) % mod;
    long long sm = ((s % mod) * (s % mod) * 2 + 1 )% mod;
    long long ms = ((s % mod) * (s % mod) * 2 - 1 + mod)% mod;
    if(tm == sm)
        cout << tm << endl;
    else if(tm == ms)
        cout << (tm + 1 + mod) % mod << endl;
    else
        cout << "no" << endl;
    return 0;
}
阅读更多
版权声明:转载时记得附上原文链接哦~ https://blog.csdn.net/qq_23323877/article/details/52384366
文章标签: 矩阵 51nod ACM
个人分类: 数学
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

51nod - 1573 分解 - 矩阵快速幂

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭