<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=95.140.92.75&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=95.140.92.75&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/95.140.92.75"/>
		<updated>2026-05-24T19:04:32Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%91%D1%8B%D1%81%D1%82%D1%80%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D0%B4%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=58786</id>
		<title>Быстрый поиск наибольшей возрастающей подпоследовательности</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%91%D1%8B%D1%81%D1%82%D1%80%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D0%B4%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=58786"/>
				<updated>2017-01-05T13:04:49Z</updated>
		
		<summary type="html">&lt;p&gt;95.140.92.75: Новая страница.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дана {{Acronym | перестановка | на самом деле может быть и мультиперестановкой }} &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;\{1, 2,~\dots,~n\}&amp;lt;/tex&amp;gt; Найти [[Задача о наибольшей возрастающей подпоследовательности | НВП]] &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(n\operatorname{log}\operatorname{log}k)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; - длина НВП.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Алгоритм &amp;lt;tex&amp;gt;O(n\operatorname{log}\operatorname{log}n)&amp;lt;/tex&amp;gt; ==&lt;br /&gt;
=== Нахождение длины НВП ===&lt;br /&gt;
==== Основная идея ====&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\pi(n)&amp;lt;/tex&amp;gt; - входная перестановка.&lt;br /&gt;
&lt;br /&gt;
Для каждой длины &amp;lt;tex&amp;gt;l = 1, 2, \dots&amp;lt;/tex&amp;gt; предполагаемой НВП находим наименьший {{Acronym | элемент| назовем его лучшим элементом для заданной длины }}, что может быть последним в возрастающей подпоследовательности длины &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, запишем их в массив &amp;lt;tex&amp;gt;B[l]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если обрабатываемый элемент &amp;lt;tex&amp;gt;\pi(i)&amp;lt;/tex&amp;gt; больше последнего элемента какой-нибудь возрастающей последовательности, он может ее увеличить. &lt;br /&gt;
&lt;br /&gt;
Будем последовательно обрабатывать элементы &amp;lt;tex&amp;gt;\pi(1), \pi(2),~\dots,~\pi(n)&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* Если &amp;lt;tex&amp;gt;\pi(i)&amp;lt;/tex&amp;gt; больше {{Acronym | &amp;lt;tex&amp;gt;\pi(1), \pi(2),~\dots~,\pi(i-1)&amp;lt;/tex&amp;gt; | всех уже полученных значений B }}, значит с ним можно сделать максимальную, из уже рассмотренных, возрастающую подпоследовательность. Записываем его в конец &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Иначе &amp;lt;tex&amp;gt;\pi(i)&amp;lt;/tex&amp;gt; становится лучшим элементом для такой длины &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, что: {{Acronym | &amp;lt;tex&amp;gt;B[l]&amp;lt;/tex&amp;gt; | предыдущее значение}}&amp;lt;tex&amp;gt; = \min \{ B[j] &amp;gt; \pi(i),~j &amp;lt; i \}&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Следует отметить, что полученный массив также образует возрастающую последовательность, соответственно целесообразно использовать [[ Приоритетные очереди | приоритетную очередь]], реализованную через [[Дерево ван Эмде Боаса]]. Таким образом получаем &amp;lt;tex&amp;gt;O(\operatorname{log}\operatorname{log} n)&amp;lt;/tex&amp;gt; амортизированного времени.&lt;br /&gt;
==== Пример ====&lt;br /&gt;
Типы операций:&lt;br /&gt;
&lt;br /&gt;
Последовательность:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=&amp;quot;leftborder&amp;quot; style=&amp;quot;color: black; background-color:#ffffcc;&amp;quot; cellpadding=&amp;quot;10&amp;quot;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tex&amp;gt;\pi_1&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;\pi_2&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;\pi_3&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;\pi_4&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;\pi_5&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;\pi_6&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;\pi_7&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;\pi_8&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;\pi_9&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|  9 || 2 || 1 || 3 || 7 || 5 || 6 || 8 || 4 &lt;br /&gt;
|}&lt;br /&gt;
Состояние очереди при каждом добавлении:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=&amp;quot;leftborder&amp;quot; style=&amp;quot;color: black; background-color:#ffffcc;&amp;quot; cellpadding=&amp;quot;10&amp;quot;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tex&amp;gt;B_1&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;B_2&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;B_3&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;B_4&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;B_5&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;~\pi_i~&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; &lt;br /&gt;
| style=&amp;quot;background:#FFCC00&amp;quot;| 9 ||   ||   ||   ||   || style=&amp;quot;background:#9886ff&amp;quot;|9&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; &lt;br /&gt;
| style=&amp;quot;background:#FFCC00&amp;quot;| 2 ||   ||   ||   ||   || style=&amp;quot;background:#9886ff&amp;quot;|2&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; &lt;br /&gt;
| style=&amp;quot;background:#FFCC00&amp;quot;| 1 ||   ||   ||   ||   || style=&amp;quot;background:#9886ff&amp;quot;|1&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; &lt;br /&gt;
| 1 || style=&amp;quot;background:#FFCC00&amp;quot;| 3 ||   ||   ||   || style=&amp;quot;background:#9886ff&amp;quot;|3&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; &lt;br /&gt;
| 1 || 3 || style=&amp;quot;background:#FFCC00&amp;quot;| 7 ||   ||   || style=&amp;quot;background:#9886ff&amp;quot;|7&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; &lt;br /&gt;
| 1 || 3 || style=&amp;quot;background:#FFCC00&amp;quot;| 5 ||   ||   || style=&amp;quot;background:#9886ff&amp;quot;|5&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; &lt;br /&gt;
| 1 || 3 || 5 || style=&amp;quot;background:#FFCC00&amp;quot;| 6 ||   || style=&amp;quot;background:#9886ff&amp;quot;|6&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; &lt;br /&gt;
| 1 || 3 || 5 || 6 || style=&amp;quot;background:#FFCC00&amp;quot;| 8 || style=&amp;quot;background:#9886ff&amp;quot;|8&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; &lt;br /&gt;
| 1 || 3 || style=&amp;quot;background:#FFCC00&amp;quot;| 4 || 6 || 8 || style=&amp;quot;background:#9886ff&amp;quot;|4&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    '''function''' LIS(&amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;[])&lt;br /&gt;
        B = priorityQueue()&lt;br /&gt;
        k = 0&lt;br /&gt;
        n = &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;.size&lt;br /&gt;
        '''for''' i = 1..n:&lt;br /&gt;
            x = &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;[i]&lt;br /&gt;
            B.insert(x)             // в любом случае добавляем в очередь&lt;br /&gt;
            '''if''' B.next(x) '''exists''' '''then'''&lt;br /&gt;
                B.delete(B.next(x)) // удаляем предыдущее значение - заменяем {{Acronym | следующий | минимальный из бОльших}} &lt;br /&gt;
            '''else'''&lt;br /&gt;
                k = k + 1           // добавляем максимальный - уже добавлен, ничего не удаляем&lt;br /&gt;
        '''return''' k&amp;lt;/code&amp;gt;&lt;br /&gt;
=== Расширение алгоритма на нахождение НВП ===&lt;br /&gt;
==== Основная идея ====&lt;br /&gt;
Будем запоминать пары: для каждого элемента записываем его &amp;quot;предшественника&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Тогда, выбрав какой-нибудь лучший элемент для максимальной длины, мы можем легко восстановить все НВП.&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    '''function''' LIS(&amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;[])&lt;br /&gt;
        B = priorityQueue()&lt;br /&gt;
        k = 0&lt;br /&gt;
        n = &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;.size&lt;br /&gt;
        &amp;lt;color = 'red'&amp;gt;predecessors = [n]&amp;lt;/color&amp;gt;&lt;br /&gt;
        '''for''' i = 1 to n&lt;br /&gt;
            x = &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;[i]&lt;br /&gt;
            B.insert(x)&lt;br /&gt;
            predecessor[x] = B.prev(x)&lt;br /&gt;
            '''if''' B.next(x) '''exists''' '''then'''&lt;br /&gt;
                B.delete(B.next(x))&lt;br /&gt;
            '''else'''&lt;br /&gt;
                k = k + 1&lt;br /&gt;
        result = []&lt;br /&gt;
        cur = B.max()&lt;br /&gt;
        result += [cur]&lt;br /&gt;
        '''while''' predecessor[cur] '''exists'''&lt;br /&gt;
            result += [predecessor[cur]]&lt;br /&gt;
            cur = predecessor[cur]&lt;br /&gt;
        '''return''' result&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
== Переименование до &amp;lt;tex&amp;gt;O(n\operatorname{log}\operatorname{log}k)&amp;lt;/tex&amp;gt; ==&lt;/div&gt;</summary>
		<author><name>95.140.92.75</name></author>	</entry>

	</feed>