<?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=217.66.156.233&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=217.66.156.233&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/217.66.156.233"/>
		<updated>2026-04-08T11:43:02Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BD%D0%B0%D0%BA%D0%B5%D1%80%D0%B0&amp;diff=52582</id>
		<title>Алгоритм Манакера</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BD%D0%B0%D0%BA%D0%B5%D1%80%D0%B0&amp;diff=52582"/>
				<updated>2016-03-10T19:52:41Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.156.233: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Шаблон:Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дана строка &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. Требуется найти &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; - длина наибольшего палиндрома нечетной длины с центром в позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d2[i]&amp;lt;/tex&amp;gt;- аналогично для палиндромов четной длины для всех &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; от 1 до &amp;lt;tex&amp;gt;|s|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Наивный алгоритм ==&lt;br /&gt;
===Идея===&lt;br /&gt;
Опишем сначала наивный алгоритм решения задачи. Чтобы посчитать ответ для позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, будем на каждом шаге увеличивать длину палиндрома с центром в &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и убеждаться, что рассматриваемая строка не перестала быть палиндромом, либо не произошел выход за границы массива. Очевидно, что такой алгоритм будет работать за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} исходная строка&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;d1, d2&amp;lt;/tex&amp;gt; {{---}} массивы для записи ответа&amp;lt;/font&amp;gt;&lt;br /&gt;
  '''for''' i = 1 '''to''' n&lt;br /&gt;
    d1[i] = 1&lt;br /&gt;
    '''while''' i - d1[i] &amp;gt; 0 '''and''' i + d1[i] &amp;lt;= n '''and''' s[i - d1[i]] == s[i + d1[i]]&lt;br /&gt;
      d1[i]++&lt;br /&gt;
    d2[i] = 0&lt;br /&gt;
    '''while''' i - d2[i] - 1 &amp;gt; 0 '''and''' i + d2[i] &amp;lt;= n '''and''' s[i - d2[i] - 1] == s[i + d2[i]]&lt;br /&gt;
      d2[i]++&lt;br /&gt;
==Алгоритм Манакера==&lt;br /&gt;
===Идея===&lt;br /&gt;
Алгоритм, который будет описан далее, отличается от наивного тем, что использует значения, посчитанные ранее. &lt;br /&gt;
Будем поддерживать границы самого правого из найденных палиндромов - &amp;lt;tex&amp;gt;[l; r]&amp;lt;/tex&amp;gt;. Итак, пусть мы хотим вычислить &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; - т.е. длину наибольшего палиндрома с центром в позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;. При этом все предыдущие значения в массиве &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уже посчитаны. Возможны два случая:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tex&amp;gt;i &amp;gt; r&amp;lt;/tex&amp;gt;, т.е. текущая позиция не попадает в границы самого правого из найденных палиндромов. Тогда просто запустим наивный алгоритм для позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# &amp;lt;tex&amp;gt;i \leq r&amp;lt;/tex&amp;gt;. Тогда попробуем воспользоваться значениями, посчитанным ранее. Отразим нашу текущую позицию внутри палиндрома &amp;lt;tex&amp;gt;[l;r] : j = (r - i) + l&amp;lt;/tex&amp;gt;. Поскольку &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; - симметричные позиции, то мы можем утверждать, &amp;lt;tex&amp;gt;d1[i] = d1[j]&amp;lt;/tex&amp;gt;. Однако надо не забыть про один граничный случай: что если &amp;lt;tex&amp;gt;i + d1[j] - 1&amp;lt;/tex&amp;gt; выходит за границы самого правого палиндрома? Так как информации о том, что происходит за границами это палинлрома у нас нет, то необходимо ограничить значение &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; следующим образом: &amp;lt;tex&amp;gt;d1[i] = min(r - i, d1[j])&amp;lt;/tex&amp;gt;. После этого запустим наивный алгоритм, который будет увеличивать значение &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt;, пока это возможно.&lt;br /&gt;
&lt;br /&gt;
После каждого шага важно не забывать обновлять значения &amp;lt;tex&amp;gt;[l;r]&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что массив &amp;lt;tex&amp;gt;d2&amp;lt;/tex&amp;gt; считается аналогичным образом, нужно лишь немного изменить индексы.&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
Приведем код, который вычисляет значения массива &amp;lt;tex&amp;gt;d1&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} исходная строка&amp;lt;/font&amp;gt;&lt;br /&gt;
 '''int''' l = 0&lt;br /&gt;
 '''int''' r = -1&lt;br /&gt;
 '''for''' i = 1 '''to''' n&lt;br /&gt;
   '''int''' k = 0&lt;br /&gt;
   '''if''' i &amp;lt;= r&lt;br /&gt;
      k = min(r - i, d[r - i + l])&lt;br /&gt;
   '''while''' i + k + 1 &amp;lt;= n '''and''' i - k - 1 &amp;gt; 0 '''and''' s[i + k + 1] == s[i - k - 1]&lt;br /&gt;
      k++&lt;br /&gt;
    d1[i] = k&lt;br /&gt;
    '''if''' i + k &amp;gt; r&lt;br /&gt;
      l = i - k&lt;br /&gt;
      r = i + k&lt;br /&gt;
&lt;br /&gt;
Вычисление значений массива &amp;lt;tex&amp;gt;d2&amp;lt;/tex&amp;gt;:&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} исходная строка&amp;lt;/font&amp;gt;&lt;br /&gt;
 '''int''' l = 0&lt;br /&gt;
 '''int''' r = -1&lt;br /&gt;
 '''for''' i = 1 '''to''' n&lt;br /&gt;
   '''int''' k = 0&lt;br /&gt;
   '''if''' i &amp;lt;= r&lt;br /&gt;
      k = min(r - i + 1, d[r - i + l + 1])&lt;br /&gt;
   '''while''' i + k &amp;lt;= n '''and''' i - k - 1 &amp;gt; 0 '''and''' s[i + k] == s[i - k - 1]&lt;br /&gt;
      k++&lt;br /&gt;
    d2[i] = k&lt;br /&gt;
    '''if''' i + k - 1 &amp;gt; r&lt;br /&gt;
      l = i - k&lt;br /&gt;
      r = i + k - 1&lt;br /&gt;
&lt;br /&gt;
===Оценка сложности===&lt;br /&gt;
Внешний цикл в приведенном алгоритме выполняется ровно &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз, где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - длина строки. Попытаемся понять, сколько раз будет выполнен внутренний цикл, ответственный за наивный подсчет значений. Заметим, что каждая итерация вложенного цикла приводит к увеличению &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; на 1. Действительно, возможны следующие случаи:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tex&amp;gt;i &amp;gt; r&amp;lt;/tex&amp;gt;, т.е. сразу будет запущен наивный алгоритм и каждая его итерация будет увеличивать значение &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; хотя бы на 1&lt;br /&gt;
# &amp;lt;tex&amp;gt;i \leq r&amp;lt;/tex&amp;gt;. Здесь опять два случая:&lt;br /&gt;
## &amp;lt;tex&amp;gt;i + d[j] - 1 \leq r&amp;lt;/tex&amp;gt;, но тогда, очевидно, ни одной итерации вложенного цикла выполнено не будет&lt;br /&gt;
## &amp;lt;tex&amp;gt;i + d[j] - 1 &amp;gt; r&amp;lt;/tex&amp;gt;,  тогда каждая итерация вложенного цикла приведет к увеличению &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; хотя бы на 1.&lt;br /&gt;
&lt;br /&gt;
Т.к. значение &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; не может увеличиваться более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз, то описанный выше алгоритм работает за линейное время.&lt;/div&gt;</summary>
		<author><name>217.66.156.233</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BD%D0%B0%D0%BA%D0%B5%D1%80%D0%B0&amp;diff=52581</id>
		<title>Алгоритм Манакера</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BD%D0%B0%D0%BA%D0%B5%D1%80%D0%B0&amp;diff=52581"/>
				<updated>2016-03-10T19:39:07Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.156.233: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Шаблон:Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дана строка &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. Требуется найти &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; - длина наибольшего палиндрома нечетной длины с центром в позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d2[i]&amp;lt;/tex&amp;gt;- аналогично для палиндромов четной длины для всех &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; от 1 до &amp;lt;tex&amp;gt;|s|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Наивный алгоритм ==&lt;br /&gt;
===Идея===&lt;br /&gt;
Опишем сначала наивный алгоритм решения задачи. Чтобы посчитать ответ для позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, будем на каждом шаге увеличивать длину палиндрома с центром в &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и убеждаться, что рассматриваемая строка не перестала быть палиндромом, либо не произошел выход за границы массива. Очевидно, что такой алгоритм будет работать за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} исходная строка&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;d1, d2&amp;lt;/tex&amp;gt; {{---}} массивы для записи ответа&amp;lt;/font&amp;gt;&lt;br /&gt;
  '''for''' i = 1 '''to''' n&lt;br /&gt;
    d1[i] = 1&lt;br /&gt;
    '''while''' i - d1[i] &amp;gt; 0 '''and''' i + d1[i] &amp;lt;= n '''and''' s[i - d1[i]] == s[i + d1[i]]&lt;br /&gt;
      d1[i]++&lt;br /&gt;
    d2[i] = 0&lt;br /&gt;
    '''while''' i - d2[i] - 1 &amp;gt; 0 '''and''' i + d2[i] &amp;lt;= n '''and''' s[i - d2[i] - 1] == s[i + d2[i]]&lt;br /&gt;
      d2[i]++&lt;br /&gt;
==Алгоритм Манакера==&lt;br /&gt;
===Идея===&lt;br /&gt;
Алгоритм, который будет описан далее, отличается от наивного тем, что использует значения, посчитанные ранее. &lt;br /&gt;
Будем поддерживать границы самого правого из найденных палиндромов - &amp;lt;tex&amp;gt;[l; r]&amp;lt;/tex&amp;gt;. Итак, пусть мы хотим вычислить &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; - т.е. длину наибольшего палиндрома с центром в позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;. При этом все предыдущие значения в массиве &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уже посчитаны. Возможны два случая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;tex&amp;gt;i &amp;gt; r&amp;lt;/tex&amp;gt;, т.е. текущая позиция не попадает в границы самого правого из найденных палиндромов. Тогда просто запустим наивный алгоритм для позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;tex&amp;gt;i \leq r&amp;lt;/tex&amp;gt;. Тогда попробуем воспользоваться значениями, посчитанным ранее. Отразим нашу текущую позицию внутри палиндрома &amp;lt;tex&amp;gt;[l;r] : j = (r - i) + l&amp;lt;/tex&amp;gt;. Поскольку &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; - симметричные позиции, то мы можем утверждать, &amp;lt;tex&amp;gt;d1[i] = d1[j]&amp;lt;/tex&amp;gt;. Однако надо не забыть про один граничный случай: что если &amp;lt;tex&amp;gt;i + d1[j] - 1&amp;lt;/tex&amp;gt; выходит за границы самого правого палиндрома? Так как информации о том, что происходит за границами это палинлрома у нас нет, то необходимо ограничить значение &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; следующим образом: &amp;lt;tex&amp;gt;d1[i] = min(r - i, d1[j])&amp;lt;/tex&amp;gt;. После этого запустим наивный алгоритм, который будет увеличивать значение &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt;, пока это возможно.&lt;br /&gt;
&lt;br /&gt;
После каждого шага важно не забывать обновлять значения &amp;lt;tex&amp;gt;[l;r]&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что массив &amp;lt;tex&amp;gt;d2&amp;lt;/tex&amp;gt; считается аналогичным образом, нужно лишь немного изменить индексы.&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
Приведем код, который вычисляет значения массива &amp;lt;tex&amp;gt;d1&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} исходная строка&amp;lt;/font&amp;gt;&lt;br /&gt;
 '''int''' l = 0&lt;br /&gt;
 '''int''' r = -1&lt;br /&gt;
 '''for''' i = 1 '''to''' n&lt;br /&gt;
   '''int''' k = 0&lt;br /&gt;
   '''if''' i &amp;lt;= r&lt;br /&gt;
      k = min(r - i, d[r - i + l])&lt;br /&gt;
   '''while''' i + k + 1 &amp;lt;= n '''and''' i - k - 1 &amp;gt; 0 '''and''' s[i + k + 1] == s[i - k - 1]&lt;br /&gt;
      k++&lt;br /&gt;
    d1[i] = k&lt;br /&gt;
    '''if''' i + k &amp;gt; r&lt;br /&gt;
      l = i - k&lt;br /&gt;
      r = i + k&lt;br /&gt;
&lt;br /&gt;
Вычисление значений массива &amp;lt;tex&amp;gt;d2&amp;lt;/tex&amp;gt;:&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} исходная строка&amp;lt;/font&amp;gt;&lt;br /&gt;
 '''int''' l = 0&lt;br /&gt;
 '''int''' r = -1&lt;br /&gt;
 '''for''' i = 1 '''to''' n&lt;br /&gt;
   '''int''' k = 0&lt;br /&gt;
   '''if''' i &amp;lt;= r&lt;br /&gt;
      k = min(r - i + 1, d[r - i + l + 1])&lt;br /&gt;
   '''while''' i + k &amp;lt;= n '''and''' i - k - 1 &amp;gt; 0 '''and''' s[i + k] == s[i - k - 1]&lt;br /&gt;
      k++&lt;br /&gt;
    d2[i] = k&lt;br /&gt;
    '''if''' i + k - 1 &amp;gt; r&lt;br /&gt;
      l = i - k&lt;br /&gt;
      r = i + k - 1&lt;/div&gt;</summary>
		<author><name>217.66.156.233</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BD%D0%B0%D0%BA%D0%B5%D1%80%D0%B0&amp;diff=52580</id>
		<title>Алгоритм Манакера</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BD%D0%B0%D0%BA%D0%B5%D1%80%D0%B0&amp;diff=52580"/>
				<updated>2016-03-10T19:08:35Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.156.233: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Шаблон:Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дана строка &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. Требуется найти &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; - длина наибольшего палиндрома нечетной длины с центром в позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d2[i]&amp;lt;/tex&amp;gt;- аналогично для палиндромов четной длины для всех &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; от 1 до &amp;lt;tex&amp;gt;|s|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Наивный алгоритм ==&lt;br /&gt;
===Идея===&lt;br /&gt;
Опишем сначала наивный алгоритм решения задачи. Чтобы посчитать ответ для позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, будем на каждом шаге увеличивать длину палиндрома с центром в &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и убеждаться, что рассматриваемая строка не перестала быть палиндромом, либо не произошел выход за границы массива. Очевидно, что такой алгоритм будет работать за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} исходная строка&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;d1, d2&amp;lt;/tex&amp;gt; {{---}} массивы для записи ответа&amp;lt;/font&amp;gt;&lt;br /&gt;
  '''for''' i = 1 '''to''' n&lt;br /&gt;
    d1[i] = 1&lt;br /&gt;
    '''while''' i - d1[i] &amp;gt; 0 '''and''' i + d1[i] &amp;lt;= n '''and''' s[i - d1[i]] == s[i + d1[i]]&lt;br /&gt;
      d1[i]++&lt;br /&gt;
    d2[i] = 0&lt;br /&gt;
    '''while''' i - d2[i] - 1 &amp;gt; 0 '''and''' i + d2[i] &amp;lt;= n '''and''' s[i - d2[i] - 1] == s[i + d2[i]]&lt;br /&gt;
      d2[i]++&lt;br /&gt;
==Алгоритм Манакера==&lt;br /&gt;
===Идея===&lt;br /&gt;
Алгоритм, который будет описан далее, отличается от наивного тем, что использует значения, посчитанные ранее. &lt;br /&gt;
Будем поддерживать границы самого правого из найденных палиндромов - &amp;lt;tex&amp;gt;[l; r]&amp;lt;/tex&amp;gt;. Итак, пусть мы хотим вычислить &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; - т.е. длину наибольшего палиндрома с центром в позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;. При этом все предыдущие значения в массиве &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уже посчитаны. Возможны два случая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;tex&amp;gt;i &amp;gt; r&amp;lt;/tex&amp;gt;, т.е. текущая позиция не попадает в границы самого правого из найденных палиндромов. Тогда просто запустим наивный алгоритм для позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;tex&amp;gt;i \leq r&amp;lt;/tex&amp;gt;. Тогда попробуем воспользоваться значениями, посчитанным ранее. Отразим нашу текущую позицию внутри палиндрома &amp;lt;tex&amp;gt;[l;r] : j = (r - i) + l&amp;lt;/tex&amp;gt;. Поскольку &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; - симметричные позиции, то мы можем утверждать, &amp;lt;tex&amp;gt;d1[i] = d1[j]&amp;lt;/tex&amp;gt;. Однако надо не забыть про один граничный случай: что если &amp;lt;tex&amp;gt;i + d1[j] - 1&amp;lt;/tex&amp;gt; выходит за границы самого правого палиндрома? Так как информации о том, что происходит за границами это палинлрома у нас нет, то необходимо ограничить значение &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; следующим образом: &amp;lt;tex&amp;gt;d1[i] = min(r - i, d1[j]). После этого запустим наивный алгоритм, который будет увеличивать значение &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt;, пока это возможно.&lt;br /&gt;
&lt;br /&gt;
Заметим, что массив &amp;lt;tex&amp;gt;d2&amp;lt;/tex&amp;gt; считается аналогичным образом, нужно лишь немного изменить индексы.&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
Приведем код, который вычисляет значения массивов &amp;lt;tex&amp;gt;d1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d2&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} исходная строка&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;d1, d2&amp;lt;/tex&amp;gt; {{---}} массивы для записи ответа&amp;lt;/font&amp;gt;&lt;br /&gt;
 '''int''' l = 0&lt;br /&gt;
 '''int''' r = -1&lt;br /&gt;
 '''for''' i = 1 '''to''' n&lt;br /&gt;
   '''int''' k = 1&lt;br /&gt;
   '''if''' i &amp;lt;= r&lt;br /&gt;
      k = k + min(r - i, d[r - i + l])&lt;br /&gt;
   '''while''' i + k &amp;lt;= n '''and''' i - k &amp;gt; 0 '''and''' s[i + k] == s[i - k]&lt;br /&gt;
      k++&lt;br /&gt;
     d1[i]++&lt;br /&gt;
   d2[i] = 0&lt;br /&gt;
   '''while''' i - d2[i] - 1 &amp;gt; 0 '''and''' i + d2[i] &amp;lt;= n '''and''' s[i - d2[i] - 1] == s[i + d2[i]]&lt;br /&gt;
     d2[i]++&lt;/div&gt;</summary>
		<author><name>217.66.156.233</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BD%D0%B0%D0%BA%D0%B5%D1%80%D0%B0&amp;diff=52579</id>
		<title>Алгоритм Манакера</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BD%D0%B0%D0%BA%D0%B5%D1%80%D0%B0&amp;diff=52579"/>
				<updated>2016-03-10T18:55:24Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.156.233: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Шаблон:Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дана строка &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. Требуется найти &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; - длина наибольшего палиндрома нечетной длины с центром в позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d2[i]&amp;lt;/tex&amp;gt;- аналогично для палиндромов четной длины для всех &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; от 1 до &amp;lt;tex&amp;gt;|s|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Наивный алгоритм ==&lt;br /&gt;
===Идея===&lt;br /&gt;
Опишем сначала наивный алгоритм решения задачи. Чтобы посчитать ответ для позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, будем на каждом шаге увеличивать длину палиндрома с центром в &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и убеждаться, что рассматриваемая строка не перестала быть палиндромом, либо не произошел выход за границы массива. Очевидно, что такой алгоритм будет работать за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} исходная строка&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;d1, d2&amp;lt;/tex&amp;gt; {{---}} массивы для записи ответа&amp;lt;/font&amp;gt;&lt;br /&gt;
  '''for''' i = 1 '''to''' n&lt;br /&gt;
    d1[i] = 1&lt;br /&gt;
    '''while''' i - d1[i] &amp;gt; 0 '''and''' i + d1[i] &amp;lt;= n '''and''' s[i - d1[i]] == s[i + d1[i]]&lt;br /&gt;
      d1[i]++&lt;br /&gt;
    d2[i] = 0&lt;br /&gt;
    '''while''' i - d2[i] - 1 &amp;gt; 0 '''and''' i + d2[i] &amp;lt;= n '''and''' s[i - d2[i] - 1] == s[i + d2[i]]&lt;br /&gt;
      d2[i]++&lt;br /&gt;
==Алгоритм Манакера==&lt;br /&gt;
===Идея===&lt;br /&gt;
Алгоритм, который будет описан далее, отличается от наивного тем, что использует значения, посчитанные ранее. &lt;br /&gt;
Будем поддерживать границы самого правого из найденных палиндромов - &amp;lt;tex&amp;gt;[l; r]&amp;lt;/tex&amp;gt;. Итак, пусть мы хотим вычислить &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; - т.е. длину наибольшего палиндрома с центром в позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;. При этом все предыдущие значения в массиве &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уже посчитаны. Возможны два случая:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;tex&amp;gt;i &amp;gt; r&amp;lt;/tex&amp;gt;, т.е. текущая позиция не попадает в границы самого правого из найденных палиндромов. Тогда просто запустим наивный алгоритм для позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;tex&amp;gt;i \leq r&amp;lt;/tex&amp;gt;. Тогда попробуем воспользоваться значениями, посчитанным ранее. Отразим нашу текущую позицию внутри палиндрома &amp;lt;tex&amp;gt;[l;r] : j = (r - i) + l&amp;lt;/tex&amp;gt;. Поскольку &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; - симметричные позиции, то мы можем утверждать, &amp;lt;tex&amp;gt;d1[i] = d1[j]&amp;lt;/tex&amp;gt;. Однако надо не забыть про один граничный случай: что если &amp;lt;tex&amp;gt;i + d1[j] - 1&amp;lt;/tex&amp;gt; выходит за границы самого правого палиндрома? Так как информации о том, что происходит за границами это палинлрома у нас нет, то необходимо ограничить значение &amp;lt;tex&amp;gt;d1[i]&amp;lt;/tex&amp;gt; следующим образом: &amp;lt;tex&amp;gt;d1[i] = min(r - i, d1[j]).&lt;/div&gt;</summary>
		<author><name>217.66.156.233</name></author>	</entry>

	</feed>