Trong khi suy nghĩ về một vấn đề, tôi nhận ra rằng tôi cần tạo ra một thuật toán hiệu quả để giải quyết các nhiệm vụ sau:
Vấn đề: chúng ta được cung cấp một hộp vuông hai chiều của cạnh có các cạnh song song với các trục. Chúng ta có thể nhìn vào nó thông qua đầu. Tuy nhiên, cũng có đoạn ngang. Mỗi phân khúc có một số nguyên Phối ( ) và -coordinates ( ) và kết nối điểm và (nhìn vào bức tranh dưới đây).
Chúng tôi muốn biết, đối với mỗi phân khúc đơn vị trên đỉnh hộp, chúng ta có thể nhìn sâu vào bên trong hộp như thế nào nếu chúng ta nhìn qua phân khúc này.
Ví dụ: cho và đoạn nằm trong hình bên dưới, kết quả là . Nhìn vào cách ánh sáng sâu có thể đi vào hộp.m = 7 ( 5 , 5 , 5 , 3 , 8 , 3 , 7 , 8 , 7 )
May mắn cho chúng tôi, cả và đều khá nhỏ và chúng tôi có thể thực hiện các tính toán ngoại tuyến.m
Thuật toán đơn giản nhất giải quyết vấn đề này là brute-force: cho mỗi phân đoạn đi qua toàn bộ mảng và cập nhật nó khi cần thiết. Tuy nhiên, nó cho chúng ta không ấn tượng lắm .
Một cải tiến tuyệt vời là sử dụng cây phân đoạn có khả năng tối đa hóa các giá trị trên phân khúc trong khi truy vấn và đọc các giá trị cuối cùng. Tôi sẽ không mô tả thêm, nhưng chúng ta thấy rằng độ phức tạp thời gian là .
Tuy nhiên, tôi đã đưa ra một thuật toán nhanh hơn:
Đề cương:
Sắp xếp các phân đoạn theo thứ tự giảm dần của phối hợp (thời gian tuyến tính bằng cách sử dụng một biến thể của sắp xếp đếm). Bây giờ lưu ý rằng nếu bất kỳ phân đoạn -unit nào đã được bao phủ bởi bất kỳ phân khúc nào trước đó, thì không có phân đoạn nào sau đây có thể ràng buộc chùm sáng đi qua phân khúc -unit này nữa. Sau đó, chúng tôi sẽ thực hiện quét dòng từ trên xuống dưới cùng của hộp.x x
Bây giờ chúng ta hãy giới thiệu một số định nghĩa: -unit phân khúc là một phân khúc ngang tưởng tượng trên quét mà -coordinates là các số nguyên và có chiều dài là 1. Mỗi phân khúc trong quá trình quét có thể là không rõ ràng (có nghĩa là, một chùm ánh sáng đi từ đầu hộp có thể đạt đến phân khúc này) hoặc được đánh dấu (trường hợp ngược lại). Hãy xem xét một phân đoạn -unit với , luôn không được đánh dấu. Chúng tôi cũng giới thiệu các bộ . Mỗi bộ sẽ chứa toàn bộ chuỗi các phân đoạn -unit được đánh dấu liên tiếp (nếu có) với dấu không được đánh dấu saux x x 1 = n x 2 = n + 1 S 0 = { 0 } , S 1 = { 1 } , Phong , S n = { n } x bộ phận.
Chúng tôi cần một cấu trúc dữ liệu có thể hoạt động trên các phân đoạn này và thiết lập hiệu quả. Chúng tôi sẽ sử dụng cấu trúc tìm kết hợp được mở rộng bởi một trường có chỉ số phân đoạn -unit tối đa (chỉ mục của phân đoạn không được đánh dấu ).
Bây giờ chúng ta có thể xử lý các phân khúc một cách hiệu quả. Giả sử bây giờ chúng tôi đang xem xét phân khúc thứ thứ tự (gọi là "truy vấn"), bắt đầu bằng và kết thúc bằng . Chúng ta cần tìm tất cả các phân đoạn -unit không được đánh dấu được chứa trong phân đoạn thứ (đây chính xác là các phân đoạn mà chùm sáng sẽ kết thúc theo cách của nó). Chúng tôi sẽ làm như sau: trước tiên, chúng tôi tìm thấy phân đoạn chưa được đánh dấu đầu tiên bên trong truy vấn ( Tìm đại diện của tập hợp chứa và lấy chỉ số tối đa của tập hợp này, đó là phân đoạn không được đánh dấu theo định nghĩa ). Sau đó, chỉ số nàyx 1 x i x 1 x y x x + 1 x ≥ x 2 được bên trong truy vấn, thêm nó vào kết quả (kết quả cho phân khúc này là ) và đánh dấu chỉ số này ( Liên minh bộ chứa và ). Sau đó lặp lại quy trình này cho đến khi chúng tôi tìm thấy tất cả các phân đoạn không được đánh dấu , nghĩa là, truy vấn Tìm tiếp theo cung cấp cho chúng tôi chỉ mục .
Lưu ý rằng mỗi hoạt động tìm kiếm kết hợp sẽ được thực hiện chỉ trong hai trường hợp: hoặc chúng tôi bắt đầu xem xét một phân khúc (có thể xảy ra lần) hoặc chúng tôi vừa đánh dấu phân khúc -unit (điều này có thể xảy ra lần). Do đó, độ phức tạp tổng thể là ( là hàm Ackermann nghịch đảo ). Nếu một cái gì đó không rõ ràng, tôi có thể giải thích thêm về điều này. Có lẽ tôi sẽ có thể thêm một số hình ảnh nếu tôi có thời gian.x n O ( ( n + m ) α ( n ) ) α
Bây giờ tôi đã đạt đến "bức tường". Tôi không thể đưa ra một thuật toán tuyến tính, mặc dù có vẻ như nó nên có một thuật toán. Vì vậy, tôi có hai câu hỏi:
- Có một thuật toán thời gian tuyến tính (nghĩa là ) giải quyết vấn đề hiển thị phân đoạn ngang?
- Nếu không, bằng chứng nào cho thấy vấn đề về tầm nhìn là ?