Trong bài toán này, chúng ta được cung cấp một mảng arr [] có kích thước N và Q truy vấn có thể có hai kiểu. Nhiệm vụ của chúng tôi là tạo một chương trình giải quyết các truy vấn để cập nhật một chỉ mục nhất định và tìm GCD trong phạm vi.
Các truy vấn là -
Loại 1 - {1, index, value} - tăng phần tử ở chỉ mục đã cho theo giá trị.
Loại 2 - {2, L, R} - tìm GCD của các phần tử trong phạm vi chỉ mục [L, R].
Mô tả sự cố - Chúng ta cần tìm GCD của các phần tử nằm trong khoảng [L, R] và trả về giá trị.
Hãy lấy một ví dụ để hiểu vấn đề,
Đầu vào
arr [] ={5, 1, 7, 3, 8}, Q =3Cueries:{{2, 2, 5}, {1, 3, 6}, {2, 2, 5}}Đầu ra
Giải thích
Phương pháp tiếp cận giải pháp
Một cách tiếp cận để giải quyết vấn đề là sử dụng Cây phân đoạn được sử dụng để xử lý trước GCD cho các mảng. Điều này sẽ giảm thời gian tính toán GCD cho mỗi truy vấn.
Tạo và làm việc với Cây phân đoạn
Cây phân đoạn mà chúng ta đang sử dụng ở đây là cây lưu trữ các phần tử của mảng dưới dạng các nút lá và GCD của các phần tử dưới dạng các nút bên trong.
Chương trình minh họa hoạt động của giải pháp của chúng tôi,
Ví dụ
#includeusing namespace std; int calcGcdRangeRec (int * st, int segL, int segR, int L, int R, int currNode) {if (L <=segL &&R> =segR ) return st [currNode]; if (segR R) trả về 0; int mid =(segL + (segR - segL) / 2); int GcdL =calcGcdRangeRec (st, segL, mid, L, R, 2 * currNode + 1); int GcdR =calcGcdRangeRec (st, mid + 1, segR, L, R, 2 * currNode + 2); return __gcd (GcdL, GcdR);} void updateArrayValueRec (int * st, int L, int R, int index, int diff, int currNode) {if (index R) return; st [currNode] =st [currNode] + diff; if (R! =L) {int mid =(L + (R - L) / 2); updateArrayValueRec (st, L, mid, index, diff, 2 * currNode + 1); updateArrayValueRec (st, mid + 1, R, index, diff, 2 * currNode + 2); }} void updateArrayValue (int arr [], int * st, int n, int index, int newVal) {if (index <0 || index> n - 1) cout <<"Không hợp lệ Nhập"; else {int diff =newVal - arr [index]; arr [index] =newVal; updateArrayValueRec (st, 0, n - 1, index, diff, 0); }} int calcGcdRange (int * st, int n, int L, int R) {if (L <0 || R> n - 1 || L> R) {cout <<"Nhập không hợp lệ"; trả về -1; } return calcGcdRangeRec (st, 0, n - 1, L, R, 0);} int constructGcdST (int arr [], int L, int R, int * st, int currNode) {if (L ==R) { st [currNode] =arr [L]; return arr [L]; } int mid =(L + (R - L) / 2); int GcdL =constructGcdST (arr, L, mid, st, currNode * 2 + 1); int GcdR =constructGcdST (arr, mid + 1, R, st, currNode * 2 + 2); st [currNode] =__gcd (GcdL, GcdR); return st [currNode];} int main () {int arr [] ={1, 3, 6, 9, 9, 11}; int n =sizeof (arr) / sizeof (arr [0]); int Q =3; truy vấn int [3] [3] ={{2, 1, 3}, {1, 1, 10}, {2, 1, 3}}; giá trị int =(int) (ceil (log2 (n))); int size =2 * (int) pow (2, value) - 1; int * st =new int [size]; constructGcdST (arr, 0, n - 1, st, 0); for (int i =0; i Đầu vào
Truy vấn 1:GCD là 3 Câu hỏi 2:Đang cập nhật giá trị! Truy vấn 3:GCD là 1