canuc80k2206·7/50

Khác Ước Chung

Nộp bài trên LQDOJ

Bài 22 · Sparse Table

Cho một dãy số nguyên dương . Với mỗi truy vấn đoạn , gọi là ước chung lớn nhất của tất cả phần tử trong đoạn đó.

Hãy đếm số vị trí thuộc mà khác .

Input

  • Dòng đầu chứa số nguyên - số phần tử của dãy.
  • Dòng thứ hai chứa số nguyên .
  • Dòng thứ ba chứa số nguyên - số truy vấn.
  • Mỗi dòng trong dòng tiếp theo chứa hai số nguyên và .

Output

  • Với mỗi truy vấn, in số phần tử khác ước chung lớn nhất của đoạn trên một dòng.

Constraints

  • .
  • .
  • trong mọi truy vấn.
  • Dãy không thay đổi trong quá trình xử lý.

Scoring

  • Subtask ( số điểm): .
  • Subtask ( số điểm): Không có giới hạn bổ sung.

Example

Test 1

Input

7
6 10 15 6 9 3 6
5
1 3
1 4
4 7
1 1
1 7

Output

3
4
3
0
7

Giải thích: Trên đoạn , ước chung lớn nhất là và chỉ phần tử ở vị trí bằng giá trị này, nên có phần tử được đếm. Đoạn chỉ chứa chính ước chung lớn nhất của nó nên kết quả bằng .

Lời giải tóm tắt
  • Phân tích: Với mỗi đoạn, trước hết cần biết GCD g. Sau đó bài toán chỉ còn là đếm số lần g xuất hiện trong đoạn rồi lấy độ dài đoạn trừ đi số đó.
  • Thuật toán: Xây Sparse Table GCD trên dãy. Đồng thời, với mỗi giá trị, lưu danh sách tăng dần các vị trí xuất hiện. Một truy vấn lấy g trong O(1), sau đó dùng lower_bound và upper_bound trên danh sách vị trí của g để đếm số lần xuất hiện trong [l,r].
  • Chứng minh tính đúng đắn: Sparse Table cho đúng GCD của toàn đoạn. Danh sách vị trí của g chứa đúng mọi chỉ số có giá trị bằng g; hiệu của hai phép tìm kiếm nhị phân là chính xác số vị trí như vậy nằm trong truy vấn. Lấy độ dài đoạn trừ đi số lượng này cho đúng số phần tử khác g.
  • Độ phức tạp: Tiền xử lý tốn O(n log n) thời gian và bộ nhớ. Mỗi truy vấn tốn O(log n).