canuc80k3501·2/50

Cổng Dịch Chuyển

Nộp bài trên LQDOJ

Bài 3.6 · Binary Lifting

Có trạng thái, mỗi trạng thái dẫn xác định sang trạng thái sau một bước. Với mỗi truy vấn , hãy xác định trạng thái đạt được sau đúng bước kể từ .

Input

  • Dòng đầu chứa và .
  • Dòng thứ hai chứa số .
  • dòng tiếp theo, mỗi dòng chứa và .

Output

  • In trạng thái cuối của từng truy vấn trên một dòng.

Constraints

  • .
  • .
  • và .

Scoring

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

Example

Test 1

Input

6 5
2 3 1 5 6 4
1 0
1 4
4 3
6 5
2 10

Output

1
2
4
5
3

Giải thích: Ba trạng thái tạo một chu trình và tạo chu trình còn lại. Chẳng hạn, từ đi năm bước theo dãy nên kết quả là .

Lời giải tóm tắt
  • Ý tưởng: Xem một bước chuyển của bài toán như một hàm xác định trên tập trạng thái. Bảng jump[b][x] lưu trạng thái đạt được từ x sau đúng 2^b bước. Mức đầu tiên mô tả một bước; mỗi mức sau ghép hai đoạn liên tiếp có cùng độ dài.
  • Ý tưởng: Khi cần thực hiện một số bước, ta phân tích số đó theo nhị phân. Với mỗi bit đang bật, cập nhật trạng thái bằng cột tương ứng của bảng. Cách ghép này đặc biệt phải giữ đúng quy ước đếm bước của đề.
  • Chứng minh đúng: Bổ đề 1. Với mọi trạng thái x, jump[0][x] là trạng thái sau đúng một bước theo định nghĩa bài toán.
  • Chứng minh đúng: Bổ đề 2. Với mọi b ≥ 0, jump[b][x] là trạng thái sau đúng 2^b bước. Bổ đề đúng ở b=0; nếu đúng ở b-1, đi 2^(b-1) bước tới trạng thái trung gian rồi đi thêm 2^(b-1) bước chính là 2^b bước.
  • Chứng minh đúng: Định lý. Thuật toán in đúng kết quả. Các lũy thừa hai ứng với bit bật tạo thành một phân hoạch của đúng số bước cần thực hiện; theo Bổ đề 2, mỗi khối được thực hiện chính xác và trạng thái sau khối trước là đầu vào của khối sau.
  • Độ phức tạp: Tiền xử lý dùng O(S log B) thời gian và bộ nhớ, với S là số trạng thái và B là cận số bước. Mỗi điểm bắt đầu hoặc truy vấn được xử lý trong O(log B).
  • Lưu ý cài đặt: Cần kiểm tra riêng quy ước ở trường hợp k=0 và bảo đảm số mức đủ cho k gần 10^9.