Hàm mũ nhanh

Cấu trúc dữ liệu và giải thuật

0.0 (0 đánh giá)
Tạo bởi Katsu Cập nhật lần cuối 14:56 15-05-2022 5.042 lượt xem 0 bình luận
Tác giả/Dịch giả: huulam3011 K9
Học nhanh

Danh sách bài học

Hàm mũ nhanh

Dẫn nhập

Trong bài học ngày hôm nay, chúng ta sẽ cùng nhau đi tìm hiểu về một kĩ thuật tính toán hàm mũ được áp dụng rất nhiều trong các bài toán liên quan đến số học. Hãy cùng nhau tìm hiểu xem nó là gì nhé!


Nội dung

Để có thể tiếp thu bài học này một cách tốt nhất, các bạn nên có những kiến thức cơ bản về:

Trong bài học ngày hôm nay, chúng ta sẽ cùng nhau tìm hiểu về:

  • Hàm mũ nhanh

Bài toán đặt ra

Ta có một bài toán như sau:

Cho một số nguyên dương n và số nguyên không âm k (n,k\leq 100). Hãy in ra giá trị của n^{k} , dữ liệu đảm bảo kết quả nhỏ hơn 10^{18}.

Ví dụ:

Input Output
3 4 81

Lời giải ban đầu

Theo đúng như định nghĩa, n^{k}=n \times n \times n \times _{\cdots} \times n (k phần tử n). Do đó, ta nghĩ đến việc dùng vòng lặp để nhân k số nguyên n với nhau.

Triển khai ý tưởng trên ra code ta có như sau

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

int n, k;

ll power(int n, int k){
    ll res = 1;
    while(k--) res *= n;
    return res;
}

int main(){
    freopen("CTDL.inp","r",stdin);
    freopen("CTDL.out","w",stdout);
    cin >> n >> k;
    cout << power(n, k) << endl;

    return 0;
}

Các bạn có thể thấy ngay độ phức tạp của chương trình trên sẽ là O(k). Vậy thì liệu có cách làm giảm thời gian thời gian không?


Nhận xét

Hãy cùng thử biến đổi một chút dựa vào định nghĩa của n^{k}.

Giả sử k chẵn thì ta có

Do đó, ta nhận thấy rằng nếu k chẵn thì chỉ cần tính n^{\frac{k}{2}} rồi nhân hai giá trị lại với nhau.

Với k lẻ thì điều gì sẽ xảy ra?

Ta thấy nếu k lẻ thì ta có thể tính n^{k} = n^{k-1} \times n. Khi này k-1 chẵn nên ta áp dụng phương pháp trên để tính n^{k-1}.

Từ hai nhận xét trên ta có thể đưa ra được quy tắc sau

Các bạn có thấy mô hình trên quen không? Đó chính là mô hình của đệ quy mà ta đã nói ở những bài trước. Do đó, ta sẽ dùng đệ quy để giải quyết bài toán này. Tuy nhiên, nếu sử dụng đệ quy thì công thức trên là chưa đủ. Các bạn có nhận ra công thức trên thiếu gì không?

Câu trả lời chính là giá trị cơ sở. Vậy thì giá trị cơ sở ở đây là gì? Ta thấy biến k luôn bị chia đôi do đó đến lúc nào đó k sẽ về 0. Mặc khác, n^{0} =1. Do đó, đây chính là giá trị cơ sở của ta.

Công thức trên đầy đủ sẽ như sau


Lời giải cải tiến

Từ công thức trên, ta có thể triển khai thành code như sau

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

int n, k;

ll power(int n, int k){
    if(k == 0) return 1;
    ll res = power(n, k / 2);
    if(k % 2) return res * res * n;
    return res * res;
}

int main(){
    freopen("CTDL.inp","r",stdin);
    freopen("CTDL.out","w",stdout);
    cin >> n >> k;
    cout << power(n, k) << endl;

    return 0;
}

Vậy thì độ phức tạp của chương trình trên sẽ là bao nhiêu? Ta thấy, qua mỗi bước, giá trị k lại bị chia đôi nên số lần gọi đệ quy là k. Do đó, độ phức tạp thuật toán là O(logk).


Kết luận

  • Qua bài này chúng ta đã nắm được về Hàm mũ nhanh
  • Bài sau chúng ta sẽ tìm hiểu về Hash
  • Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”.

Tải xuống

Tài liệu

Nhằm phục vụ mục đích học tập Offline của cộng đồng, Kteam hỗ trợ tính năng lưu trữ nội dung bài học Hàm mũ nhanh dưới dạng file PDF trong link bên dưới.

Ngoài ra, bạn cũng có thể tìm thấy các tài liệu được đóng góp từ cộng đồng ở mục TÀI LIỆU trên thư viện Howkteam.com

Đừng quên likeshare để ủng hộ Kteam và tác giả nhé!


Thảo luận

Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.

Nội dung bài viết

Tác giả/Dịch giả

Mình là Nguyễn Hữu Lâm, một người có niềm đam mê rất lớn đối với lập trình. Hiện tại, mình đang là sinh viên Khoa học máy tính của Đại học Bách Khoa Hà Nội. Mong muốn của mình là có thể chia sẻ những kiến thức mà bản thân có cho mọi người, học hỏi, kết bạn với tất cả những người có cùng đam mê với mình.


K9

Nhà sáng lập Howkteam.com, KQuiz.vn & tác giả các khóa học C#, Auto, Unity3D, Python....

Với mong muốn mang đến kiến thức chất lượng, miễn phí cho mọi người, với tâm huyết phá bỏ rào cản kiến thức từ việc giáo dục thu phí. Tôi đã cùng đội ngũ Kteam đã lập nên trang website này để thế giới phẳng hơn.
Hãy cùng chúng tôi lan tỏa kiến thức đến cộng đồng! 

Khóa học

Cấu trúc dữ liệu và giải thuật

Bạn đã từng đau đầu với các cấu trúc stack, queue,.. hoặc cảm thấy cực kỳ khó khăn với các thuật toán sắp xếp, tìm kiếm được sử dụng trong lập trình. Đừng lo lắng! Trong khoá học này, chúng ta sẽ cùng nhau tìm hiểu một cách đơn giản nhất về cấu trúc dữ liệu và giải thuật, cũng như giúp bạn nắm rõ hơn về các kiến thức này.

Hãy cùng xem cấu trúc dữ liệu và giải thuật có gì đáng sợ không nhé!

Đánh giá

Bình luận

Để bình luận, bạn cần đăng nhập bằng tài khoản Howkteam.

Đăng nhập
Không có video.