Số học 3 - Tính (a^b) % c
Nguồn: HackerEarth và 1 số bài viết trên Wikipedia
Người dịch: Bùi Việt Dũng
Xét bài toán tính
Thuật toán "ngây thơ"¶
long long power(long long a, long long b, long long c) {
long long ans = 1;
for(int i = 1; i <= b; i++) {
ans *= a;
ans %= c;
}
return ans;
}
ans = ans % c
). Ta làm được vậy là nhờ tính chất Vì vậy trong code trên ta tính
Độ phức tạp của thuật toán:
Thuật toán "chia để trị"¶
Dễ dàng nhận thấy thuật toán trên không hiệu quả, vì thế ta cần tìm thuật toán hiệu quả hơn. Ta có thể giải bài toán này với độ phức tạp
Ta biết rằng
int sqr(int x) {
return x*x;
}
int pow(int a, int b, int MOD) {
if (b == 0) return 1 % MOD;
else
if (b % 2 == 0)
return sqr(pow(a, b/2)) % MOD;
else
return a * (sqr(pow(a, b/2)) % MOD) % MOD;
}
Giả sử ta có
-
Do
lẻ, nên hàm gọi hàm để tính -
Trong hàm
, do chẵn nên -
Trong hàm
, do lẻ nên . -
Trong hàm
, do nên ta trả về 1. -
Quay lại hàm
: hàm này trả về giá trị 2. -
Quay lại hàm
: hàm này trả về giá trị 4. -
Quay lại hàm
: hàm này trả về giá trị .
Vậy ta có
Độ phức tạp của thuật toán: