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

来源:互联网 发布:《网络黑白》 编辑:程序博客网 时间:2024/05/17 02:37

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;}
0 0
原创粉丝点击