Під час роздумів над однією проблемою я зрозумів, що мені потрібно створити ефективний алгоритм для вирішення наступного завдання:
Проблема: нам дається двовимірне квадратне поле зі сторони , сторони якого паралельні осям. Ми можемо заглянути в нього через верх. Однак є і горизонтальних сегментів. Кожен сегмент має ціле число -координат ( ) і -координати ( ) і з'єднує точки та (дивіться на малюнок нижче).m y 0 ≤ y ≤ n x 0 ≤ x 1 < x 2 ≤ n ( x 1 , y ) ( x 2 , y )
Ми хотіли б знати, для кожного сегмента у верхній частині коробки, наскільки глибоко ми можемо виглядати вертикально всередині коробки, якщо переглянемо цей сегмент.
Формально для ми хочемо знайти .max i : [ x , x + 1 ] ⊆ [ x 1 , i , x 2 , i ] y i
Приклад: задані і сегментів, розташованих як на малюнку нижче, результат . Подивіться, як глибоке світло може потрапити в коробку.
До щастя для нас, як і є досить малі , і ми можемо зробити обчислення офф-лайн.
Найпростіший алгоритм вирішення цієї проблеми - груба сила: для кожного сегмента пройдіть весь масив і оновіть його, де необхідно. Однак це дає нам не дуже вражаючий .
Велике вдосконалення полягає у використанні сегментного дерева, яке здатне максимізувати значення на сегменті під час запиту та читати кінцеві значення. Я не опишу його далі, але ми бачимо, що часова складність становить .
Однак я придумав більш швидкий алгоритм:
Контур:
Сортуйте відрізки у порядку зменшення -координати (лінійний час, використовуючи варіацію сортування підрахунку). Тепер зауважте, що якщо будь- який сегмент -одиниці раніше був охоплений будь-яким сегментом, жоден наступний сегмент вже не може зв'язати промінь світла, що проходить через цей сегмент -одиниці. Тоді зробимо підмітання лінії зверху до нижньої частини коробки.x x
Тепер введемо кілька визначень: -одиничний сегмент - це уявний горизонтальний відрізок на розгортці, -координати якого є цілими числами, а довжина - 1. Кожен сегмент під час процесу розгортання може бути або немаркованим (тобто, промінь світла, що йде від У верхній частині поля може бути досягнутий цей відрізок) або позначений (навпроти випадку). Розглянемо відрізок -одиниці з , завжди без позначення. Введемо також множини . Кожен набір буде містити цілу послідовність послідовно позначених сегментів -unit (якщо такі є) із наступним немаркованим позначеннямx x x 1 = n x 2 = n + 1 S 0 = { 0 } , S 1 = { 1 } , ... , S n = { n } x сегмент.
Нам потрібна структура даних, яка здатна працювати на цих сегментах та встановлювати ефективно. Ми будемо використовувати структуру find-union, розширену полем, що містить максимальний індекс сегмента -unit (індекс немаркованого сегмента).
Тепер ми можемо ефективно обробляти сегменти. Скажімо, зараз ми розглядаємо порядок -го сегмента (називаємо його "запит"), який починається з і закінчується в . Нам потрібно знайти всі немарковані сегменти -одиниці, які містяться всередині -го сегмента (саме такі сегменти, на яких промінь світла закінчиться). Ми зробимо наступне: по-перше, ми знаходимо перший немаркований сегмент всередині запиту ( Знайдіть представника набору, в якому міститься , і отримаємо максимум індексу цього набору, який є неозначеним сегментом за визначенням ). Тоді цей показникx 1 x 2 x i x 1 x y x x + 1 x ≥ x 2 знаходиться всередині запиту, додайте його до результату (результат для цього сегмента ) і позначте цей індекс ( набори об'єднань, що містять і ). Потім повторіть цю процедуру, поки ми не знайдемо всі немарковані сегменти, тобто наступний пошук знайде нам індекс .
Зауважте, що кожна операція пошуку об'єднання буде виконана лише у двох випадках: або ми починаємо розглядати сегмент (що може статися разів), або ми лише позначили сегмент -unit (це може статися разів). Таким чином, загальна складність становить ( - обернена функція Акермана ). Якщо щось не зрозуміло, я можу детальніше зупинитися на цьому. Можливо, я зможу додати кілька фотографій, якщо матиму час.
Тепер я досяг «стіни». Я не можу придумати лінійний алгоритм, хоча, здається, він повинен бути. Отже, у мене є два питання:
- Чи існує алгоритм лінійного часу (тобто ), що вирішує задачу про видимість горизонтального сегмента?
- Якщо ні, що є доказом того, що проблема видимості - ?