1. 程式人生 > >快速冪模板(java)

快速冪模板(java)

知道快速冪首先要知道(a * b)%c=(a%c)*(b%c)
還要知道 a^b= a^(2 *b/2)=a^2的b/2次方
當換成int型別需要考慮奇偶型做不同處理
那麼冪分為奇偶數考慮

  1. b%2=0: ab= a2*(b/2)=(a2)b/2
  2. b%2=1:ab=a* a2*(b/2)=a*(a2)b/2(因為b/2之後為基數數值變小了(int)型別。5/2=2,2*(5/2)=4一樣)。
  • 這樣發現如果求餘數的話就可以用遞迴的思想。
  • 比如求2100000%107.那麼就是((2%107)(2%107))50000=450000=((4%107)(4%107))25000=1625000你可以看得出這三步計算就省了近75000次計算。數值越大效果越明顯。
    下面給出java模板:

    輸出2n%1000000007的值
    非遞迴版
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		// TODO 自動生成的方法存根
		Scanner sc=new Scanner(System.in);
		int t=sc.nextInt();
		for(int i=0;i<t;i++)
		{
			long b=sc.nextLong();
			long c=1000000007;long a=2;
			long res = 1;
	        a %= c;
	        for
(; b != 0; b /= 2) { if (b % 2 == 1) res = (res * a) % c; a = (a * a) % c; } System.out.println(res); } } }

遞迴版(用的比較多)

import java.util.Scanner;
public class Main {
   static long c=1000000007;
	public static void main(String[] args) {
		Scanner sc =
new Scanner(System.in); int t=sc.nextInt(); for(int i=0;i<t;i++) { long a=2; long b=sc.nextLong(); long value=divide((long)2,b); System.out.println(value%c); } } private static long divide(long a,long b) { if(b==0)return 1; else if(b%2==0) {return divide((a%c)*(a%c),b/2)%c;} else return a%c*divide((a%c)*(a%c),(b-1)/2)%c; } }