【问题标题】:Is this code of matrix expo logarithmic?这个矩阵博览会的代码是对数的吗?
【发布时间】:2014-09-05 13:47:23
【问题描述】:

我想以对数时间计算第 n 个斐波那契数。所以,我写了这个函数

vector<vector<ll> > expon(ll k)
{
    if(k==1)
    {
        vector<vector<ll>> A({{1,1},{1,0}});
        return A;
    }
    auto A = expon(k/2);
    ll tmp[2][2] = {{0,0},{0,0}};
    for(int i=0;i<2;++i)
        for(int j=0;j<2;++j)
            for(int k=0;k<2;++k)
                tmp[i][j] += (A[i][k]*A[k][j])%modv;

    vector<vector<ll>> B({{tmp[0][0],tmp[0][1]},{tmp[1][0],tmp[1][1]}});
    if(k%2)
        return vector<vector<ll>>({{(tmp[0][0]+tmp[0][1])%modv,tmp[0][0]},{(tmp[1][0]+tmp[1][1])%modv,tmp[1][0]}});
    else
        return B;
}

但有些我认为它花费了太多时间。所以我想知道,它实际上是对数吗?我的意思是我的代码。

【问题讨论】:

  • "logarithmic" 可能是复杂度,这并不意味着算法很快:)
  • 时间太多怎么办?您是否使用过优化标志进行编译?与k相比,运行时间增加了多少?

标签: c++ algorithm time-complexity matrix-multiplication fibonacci


【解决方案1】:

复杂性是对数的,但实现并不理想。您不需要递归,也不需要为矩阵的每个幂创建单独的向量实例。另一句话-您有重复的变量k,这将根据编译器设置导致警告。

有一种方法可以检查给定的代码 sn-p 是否为对数 - 测量输入 n、n^2、n^4 所需的时间。如果复杂性是对数的,则每次测试的时间应该是前一次测试的两倍(还请记住,测量可能在短时间内不准确)。

【讨论】:

    【解决方案2】:

    您的算法是 O(k*logn),这在技术上是 O(logn) 但常数 k 可能很大,因为您在每次递归时创建向量,即内存分配所以很慢。

    尝试使用迭代解决方案:-

    mat ans =[1,1,1,1];
    
    while(k>0) {
    
      if(k&1) {
    
           ans = ans*a;
      }
      k=k>>1;
      a = a*a;
    }
    

    如您所见,这是O(logn),不需要重新分配,而是两个 2X2 矩阵。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-28
      • 1970-01-01
      • 2017-03-04
      • 2014-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多