快速幂 ,快速幂优化,矩形快速幂(java)

博客介绍了快速幂形式、快速乘法幂优化,阐述幂与乘法、加法的转换,还提及矩阵快速幂,即把快速幂里的1换成单位矩阵进行矩阵相乘。最后以蓝桥杯加强的斐波那契问题为例,求特定条件下斐波那契数列和对f(m)取模的值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快速幂形式

public static int f(int a,int b,int c){
          int ans =1;
          int base=a;
          while(b!=0){
              if((b&1)!=0)
                 ans=(ans*base)%c;
              base=(base*base)%c;
        } 
           return ans;
    }        

快速乘法幂(优化)

幂转换成乘法,乘法转化成加法

 public static int f(int a,int b,int c){
         int ans = 0;
         int base=a;
         while(b!=0){
             if((b&1)!=0)
                 ans=(ans+base)%c;
             base=(base+base)%c;
             b>>=1;
         }
         return ans;
     }
    public static int f1(int a,int b,int c){    
        int ans =1;
        int base = a;
        while(b!=0){
            if((b&1)!=0)
                ans= f(ans, base, c);
            base=f(base, base, c);
            b>>=1;
        }
        return ans;
    }

矩阵快速幂

将快速幂里边的1换成一个单位矩阵,然后利用矩阵相乘。

public static long[][] mut(int k,int n,long[][]A){
        long [][]res = new long[n][n];
        for(int i=0;i<res.length;i++)
            res[i][i]=1;
            while(k!=0){
                if((k&1)!=0)
                    res=f(res,A);
                A=f(A,A);
                k>>=1;
            }
            return res;
    }
    public static long[][] f(long[][]A,long[][] B){
        long res[][]=new long[A.length][B.length];
        for(int i=0;i<res.length;i++)
            for(int j=0;j<res[0].length;j++){
                for(int k=0;k<B.length;k++){
                    res[i][j]+=A[i][k]*B[k][j];
                }
            }
        return res;
    }

 例题:蓝桥杯 --加强的斐波那契

斐波那契数列大家都非常熟悉。它的定义是: 

  f(x)  =  1  ....  (x=1,2) 
  f(x)  =  f(x-1)  +  f(x-2)  ....  (x> 2) 

  对于给定的整数  n  和  m,我们希望求出: 
  f(1)  +  f(2)  +  ...  +  f(n)  的值。但这个值可能非常大,所以我们把它对  f(m)  取模。 
 

 
import java.util.*;
       
public class Main8 {   //基本上是按模板写的
     
    public static long[][] mut(int k,int n,long[][]A){
        long [][]res = new long[n][n];
        res[1][1]=1;
        res[1][0]=0;
        res[0][1]=0;
        res[0][0]=1;
            while(k!=0){
                if((k&1)!=0)
                    res=f(res,A);
                A=f(A,A);
                k>>=1;
            }
            return res;
    }
    public static long[][] f(long[][]A,long[][] B){
        long res[][]=new long[A.length][B.length];
        for(int i=0;i<res.length;i++)
            for(int j=0;j<res[0].length;j++){
                for(int k=0;k<B.length;k++){
                    res[i][j]+=A[i][k]*B[k][j];
                }
            }
        return res;
    } 
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            long a[][]=new long [2][2];
             a[0][0]=1;
             a[1][1]=0;
             a[0][1]=1;
             a[1][0]=1;
            long d[][]=mut(n-1,2,a );
            System.out.println(d[0][0]%1000000009);
 
        }
    }        

 

转载于:https://www.cnblogs.com/ls-pankong/p/10553729.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值