Matrix Exponentiation Algorithm for large values of N

后端 未结 2 1261
长发绾君心
长发绾君心 2021-01-20 15:51

I want to calculate the Fibonacci of very large value of N ie. 10^6 with a complexity of O(logN). Here is my code but it gives the result for 10^6 in 30 seconds which is ver

2条回答
  •  一向
    一向 (楼主)
    2021-01-20 16:30

    I get a more reasonable - although still very slow - time of real 0m2.335s using your code.

    The algorithm to compute the Fibonacci numbers is okay (there are some tweaks that could speed it up somewhat, but nothing very dramatic), so the problem is that operations on large BigIntegers are slow, and F(10^6) has nearly 700,000 bits.

    Since you want to compute the remainder modulo mod = 10^9 + 7, and (mod-1)^2 fits in a long, you can get a much faster implementation using longs instead of BigIntegers, computing the remainder in each step. The direct transcription

    public class FiboL {
    
        static final long mod = 1000000007L;
    
         static long fibo(long n){
    
              long F[][] = {{1,1},{1,0}};
    
              if(n == 0)
                return 0;
              power(F, n-1);
                return F[0][0]; //.mod(mod);
            }
    
        static void power(long F[][], long n){
    
              if( n == 0 || n == 1)
                  return;
              long M[][] = {{1,1},{1,0}};
    
              power(F, n/2);
              multiply(F, F);
    
              if( n%2 != 0 )
                 multiply(F, M);
            }
    
        static void multiply(long F[][], long M[][]){
    
              long x =  (F[0][0] * M[0][0]) % mod + (F[0][1] * M[1][0]) % mod;
              long y =  (F[0][0] * M[0][1]) % mod + (F[0][1] * M[1][1]) % mod;
              long z =  (F[1][0] * M[0][0]) % mod + (F[1][1] * M[1][0]) % mod;
              long w =  (F[1][0] * M[0][1]) % mod + (F[1][1] * M[1][1]) % mod;
    
              F[0][0] = x % mod;
              F[0][1] = y % mod;
              F[1][0] = z % mod;
              F[1][1] = w % mod;
        }
        public static void main(String[] args) {
            System.out.println(fibo(1000000));
        }
    }
    

    runs in real 0m0.083s.

提交回复
热议问题