問題:算法
Your task is to calculate a^b mod 1337 where a is a positive integer and b is an extremely large positive integer given in the form of an array.數組
Example1:函數
a = 2 b = [3] Result: 8
Example2:spa
a = 2 b = [1,0] Result: 1024
解決:orm
① 暴力破解。當數組b超過必定的範圍以後Math.pow(a,b)會超出整數的範圍,致使以後結果都變爲0,因此,只能找更好的方法。rem
② 因爲任意一個數都是2的次冪的和。因此,與Pow(x, n)的處理方法相似,都要對其對半縮小,但要注意每次都要對1337取餘。注意,因爲給定的指數b是一個一維數組的表示方法,咱們要是折半縮小處理起來確定十分不方便,因此咱們採用按位來處理,好比2^23 = (2^2)^10 * 2^3, 因此咱們能夠從b的最高位開始,算出個結果存入res,而後到下一位是,res的十次方再乘以a的該位次方再對1337取餘。it
理論支持(轉冪算法):io
(a^b) mod c = ((a mod c)^b) mod c ----公式1ast
(x*y) mod c = ((x mod c) * (y mod c)) mod c : 積的取餘等於取餘的積的取餘。 -----公式2form
class Solution {//9ms
public int superPow(int a, int[] b) {
int res = 1;
for (int i = 0;i < b.length;i ++){
res = (pow(res,10) * pow(a,b[i])) % 1337;
}
return res;
}
public int pow(int x,int n){
if (n == 0) return 1;
if (n == 1) return x % 1337;
return (pow(x,n / 2) * pow(x,n - n /2)) % 1337;
}
}
② 快速冪算法:
class Solution {//601ms
public int superPow(int a, int[] b) {
if (b.length == 0 || isZero(b)){
return 1;
}
a = a % 1337;
boolean flag = false;//標記次冪是否爲奇數
if (b[b.length - 1] % 2 == 1){
flag = true;//次冪是奇數
}
div(b,2);
int res = superPow(a,b);
res = (res * res) % 1337;
if (flag){
res = (res * a) % 1337;
}
return res;
}
public boolean isZero(int[] num){//判斷數組組成的整數是否爲0
for (int i = num.length - 1;i >= 0;i --){
if (num[i] > 0){
return false;
}
}
return true;
}
public void div(int[] x,int y){//將次冪折半
int tmp = 0;
for (int i = 0;i < x.length;i ++){
x[i] += tmp * 10;
tmp = x[i] % y;
x[i] = x[i] / y;
}
}
}
③ 快速冪算法+歐拉函數
除了1及其自己,1137只能被7和191整除,a^b有以下規律:
(1)首先,若是a有除數7和191,那麼a % 1337 == 0,答案是0。
(2)若是a既沒有除數7也沒有191,那麼a和1337是互質的,因此有 a^b%c = a^(b%phi(c))%c
即a ^ b % 1337 = a ^ (b % phi(1337)) % 1337 = a^(b % 1140) % 1337。
(3)最後,一個可能有7或191的除數,這是類似的。
【注】對正整數n,歐拉函數{\displaystyle \varphi (n)}是小於或等於n的正整數中與n互質的數的數目。
(1) p^k型歐拉函數:
若N是質數p(即N=p), φ(n)= φ(p)=p-p^(k-1)=p-1。
若N是質數p的k次冪(即N=p^k),φ(n)=p^k-p^(k-1)=(p-1)p^(k-1)。
(2)mn型歐拉函數
設n爲正整數,以φ(n)表示不超過n且與n互素的正整數的個數,稱爲n的歐拉函數值。若m,n互質,φ(mn)=(m-1)(n-1)=φ(m)φ(n)。
(3)特殊性質:
若n爲奇數時,φ(2n)=φ(n)。
對於任何兩個互質 的正整數a,n(n>2)有:a^φ(n)=1 mod n (恆等於)此公式即 歐拉定理
當n=p 且 a與素數p互質(即:gcd(a,p)=1)則上式有: a^(p-1)=1 mod n (恆等於)此公式即 費馬小定理
class Solution { //2ms
public int superPow(int a, int[] b) {
int c = 1337;
int phi = euler(c);//1140
int n = 0;
for (int i = 0;i < b.length;i ++){
n = n * 10 + b[i];
n %= phi;
}
return fastPow(a,n,c);
}
public int fastPow(int a,int b,int c){
a %= c;
int res = 1;
while(b != 0){
if ((b & 1) != 0) res = res * a % c;//奇數
a = a * a % c;
b >>= 1;//除2
}
return res;
}
public int euler(int n){ int res = n; for (int i = 2;i * i <= n;i ++){ if (n % i == 0){ res = res / i * (i - 1); while(n % i == 0){ n /= i; } } } if (n > 1){ res = res / n * (n - 1); } return res; } }