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

原创 2016年08月31日 14:01:10

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;
}
版权声明:转载时记得附上原文链接哦~

矩阵快速幂总结

矩阵快速幂 基础知识:(会基础的直接看应用部分) (1) 矩阵乘法 简单的说矩阵就是二维数组,数存在里面,矩阵乘法的规则:A*B=C 其中c[i][j]为A的第i行与B的第j列对应乘积的和,即: ...
  • wust_zzwh
  • wust_zzwh
  • 2016年11月25日 15:40
  • 8006

算法学习 - 快速幂和矩阵快速幂(复杂度Olog(n))C++实现

快速幂 快速幂顾名思义,就是快速算某个数的多少次幂。其时间复杂度为 O(log₂N), 与朴素的O(N)相比效率有了极大的提高。 快速幂实现原理 快速幂的原理比较好懂,就是说假如我们...
  • chenfs1992
  • chenfs1992
  • 2014年12月24日 22:51
  • 7716

POJ3070矩阵快速幂求Fib

欲哭无泪。。。。。比赛的时候都敲不出来。。 Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Tota...
  • u012350533
  • u012350533
  • 2013年10月08日 23:50
  • 931

快速幂或者矩阵快速幂

快速幂或者矩阵快速幂在算指数时是很高效的,他的基本原理是二进制,下面的A可以是一个数也可以是一个矩阵(本文特指方阵),若是数就是快速幂算法,若是矩阵就是矩阵快速幂算法,用c++只需把矩阵设成一个类就可...
  • u011401504
  • u011401504
  • 2013年08月04日 22:17
  • 10033

java实现矩阵快速幂算法

java实现矩阵快速幂算法
  • y937498174
  • y937498174
  • 2015年04月24日 09:53
  • 1117

[51nod1383&1048]整数分解为2的幂

题目大意任何正整数都能分解成2的幂,给定整数N,求N的此类划分方法的数量!比如N = 7时,共有6种划分方法。7=1+1+1+1+1+1+1 =1+1+1+1+1+2 =1+1+1+2+2...
  • WorldWide_D
  • WorldWide_D
  • 2017年01月05日 12:28
  • 671

一类常见的矩阵快速幂题型 总结

Googlecode jam 2008 Round 1A(c.Numbers) 【题意】计算的小数点前三位数,不足三位补0,正整数n的最大值为20亿。 【前提】:满足 的值在【0,1】范围 首...
  • u013050857
  • u013050857
  • 2015年09月21日 23:59
  • 1024

快速幂,矩阵快速幂原理介绍

快速幂:复杂度为logn,比普通的n快了很多了.原理 :以求a的b次方来介绍: 首先把b转换成二进制数 该二进制数第i位的权为 2^i - 1 . 比如 : 11的二进制是1011 11 = 2³×...
  • Anxdada
  • Anxdada
  • 2017年06月21日 13:49
  • 274

C++_(矩阵)快速幂

#include #include using namespace std; const int MOD = 1000;int POW(long long &num); int times; lon...
  • a7055117a
  • a7055117a
  • 2016年05月14日 20:35
  • 915

HDU 2276 & FZU 1692 (矩阵快速幂+循环同构优化)

HDU 2276题意:给定一个01**字符串环**(20 比如当前的状态为100101那么一秒过后的状态为010111。思路:用公式表示变化状态其实就是: ai=(a(i+n−1)%n+ai)%2...
  • qq_15714857
  • qq_15714857
  • 2015年08月16日 22:26
  • 716
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:51nod - 1573 分解 - 矩阵快速幂
举报原因:
原因补充:

(最多只允许输入30个字)