快速冪形式java
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; }
快速乘法冪(優化)優化
冪轉換成乘法,乘法轉化成加法spa
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; }
矩陣快速冪code
將快速冪裏邊的1換成一個單位矩陣,而後利用矩陣相乘。blog
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; }
例題:藍橋杯 --增強的斐波那契模板
斐波那契數列你們都很是熟悉。它的定義是: class
f(x) = 1 .... (x=1,2)
f(x) = f(x-1) + f(x-2) .... (x> 2) import
對於給定的整數 n 和 m,咱們但願求出:
f(1) + f(2) + ... + f(n) 的值。但這個值可能很是大,因此咱們把它對 f(m) 取模。
im
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); } }