Статья Автор: Деникина Н.В., Деникин А.В.

Самоподобные строки

Кодирование информации · Блок 2§6
SilverTests.ru · Подготовка к ИТМОТеория + паттерны + задания
Самоподобные строки

Рекурсивное построение, поиск символа, подсчёт — фирменная тема ИТМО


1Что такое самоподобная строка

Строка строится по правилу подстановки: на каждом шаге каждый символ заменяется на фрагмент (или между символами вставляется новый). Строка растёт экспоненциально, но сохраняет регулярную структуру.

Три типовых конструкции

тип 1: подстановка
// Туэ-Морс: A → AB, B → BA
S₀ = A
S₁ = AB
S₂ = ABBA
S₃ = ABBABAAB
// длина: L(n) = 2ⁿ
тип 2: вставка
// Между каждой парой вставляется новый символ
S₀ = AB
S₁ = ACB       // вставили C
S₂ = ADCDB     // вставили D между каждой парой
// длина: L(n+1) = 2L(n) − 1
тип 3: конкатенация
// S(n+1) = S(n) + X + S(n)
S₀ = A
S₁ = ABA
S₂ = ABACABA
S₃ = ABACABADABACABA
// длина: L(n+1) = 2L(n) + 1

На ИТМО правило всегда дают явно. Задача — разглядеть структуру и построить рекурсию.


2Рекурсия длины и замкнутая формула

Почти всегда длина подчиняется линейной рекурсии:

L(n+1) = a × L(n) + c
a — коэффициент роста, c — добавка на каждом шаге

Замкнутая формула

вывод
// Пусть T(n) = L(n) + c/(a−1). Тогда T(n+1) = a·T(n)
L(n) = (L(0) + c/(a−1)) × aⁿ − c/(a−1)   (при a ≠ 1)

Справочник типовых рекурсий

Правило Рекурсия L(n) при L(0)=1
Каждый символ → блок из k L(n+1) = k·L(n) kⁿ
Вставка между парами L(n+1) = 2L(n) − 1 1 (не растёт!)
S(n+1) = S(n) + X + S(n) L(n+1) = 2L(n) + |X| 2ⁿ⁺¹−1 при |X|=1
Подстановка (Туэ-Морс) L(n+1) = 2L(n) 2ⁿ
Лайфхак: на олимпиаде не надо помнить замкнутую формулу — достаточно посчитать L(0)..L(N) по рекурсии. Замкнутая форма нужна только при N ~ 10⁹.

3Рекурсивный спуск: символ на позиции p

Это ключевая техника для задач ИТМО. Позиция p огромная (до 10⁹), но символ находится за O(N) шагов.

Алгоритм для типа «конкатенация»: S(n) = S(n−1) + X + S(n−1)

алгоритм
1. Вычислить L(0), L(1), ..., L(N) — найти мин. N: L(N) ≥ p
2. Определить, куда попадает p:
   • p ≤ L(N−1)     → левая копия S(N−1), оставить p
   • p = L(N−1) + 1 → разделитель X (ответ!)
   • p > L(N−1) + 1 → правая копия: p' = p − L(N−1) − |X|
3. Уменьшить N на 1, повторять с шага 2

Алгоритм для типа «вставка между парами»

алгоритм
// В S(n) нечётные позиции = символы S(n−1)
// Чётные позиции = вставленный символ шага n

1. p чётное   → вставленный символ шага n (ответ!)
2. p нечётное → спуск: p' = (p+1)/2, n' = n−1

Алгоритм для типа «подстановка» (Туэ-Морс)

Туэ-Морс
// S(n) = [первая половина = S(n−1)] [вторая = S(n−1) с A↔B]

1. p ≤ L(n)/2 → левая половина, без инверсии
2. p > L(n)/2 → правая половина, инверсия A↔B, p' = p − L(n)/2
3. Считаем число инверсий. Если нечётное — меняем ответ.

// Пример: S₃[5], L(3)=8
p=5 > 4 → правая, инверсия, p'=1, n=2
p=1 ≤ 2 → левая, n=1
p=1 ≤ 1 → левая, n=0
S₀[1] = A, инверсий: 1 (нечёт) → B ✓

Во всех случаях строку целиком строить не нужно. Спуск работает за O(log p) шагов.


4Подсчёт символов

Вторая частая подзадача: сколько раз символ X встречается в S(n)?

метод
// Правило: A → α, B → β
// count_A(α) = число A в строке α

a(n+1) = count_A(α) × a(n) + count_A(β) × b(n)
b(n+1) = count_B(α) × a(n) + count_B(β) × b(n)

// Пример: A→ABA (2A, 1B), B→B (0A, 1B)
a(n+1) = 2·a(n) + 0·b(n) = 2a(n)
b(n+1) = 1·a(n) + 1·b(n) = a(n) + b(n)

n:  0  1  2   3
a:  1  2  4  8
b:  0  1  3  7
L:  1  3  7  15

На ИТМО матричную форму обычно не требуют — достаточно рекурсии.


5Полный олимпиадный разбор

Условие (в стиле финала ИТМО)

S₀ = «AB». На каждом шаге между каждой парой соседних символов вставляется новый: на шаге 1 — C, на шаге 2 — D, на шаге k — буква с номером k+2. Найти символ на позиции 1000 в S₁₀.

шаг 1: длины
L(n+1) = 2L(n) − 1
L: 2, 3, 5, 9, 17, 33, 65, 129, 257, 513, 1025
// L(10) = 1025 ≥ 1000 ✓
шаг 2: спуск
// Нечётные позиции → символы S(n−1)
// Чётные позиции → вставленный символ шага n

p = 1000, n = 10
1000 чётное → символ шага 10 → буква #12 = «L»
// Готово за ОДИН шаг!

// А если бы p = 999:
// 999 нечётное → p' = 500, n = 9
// 500 чётное → символ шага 9 → буква #11 = «K»
Общий принцип: при вставке между парами чётные позиции — известны сразу, нечётные — один шаг спуска. Максимум N шагов.

6Чек-лист
№ Действие
1 Выписать S₀, S₁, S₂, S₃ вручную — увидеть паттерн
2 Записать рекурсию L(n+1) = f(L(n))
3 Определить структуру: S(n) = [часть 1] + [середина] + [часть 2]
4 «Символ на позиции p» → рекурсивный спуск
5 «Сколько символов X» → рекурсия для количества
6 Проверить ответ на маленьком примере

Проверь себя8 заданий
 
 
1 / 8
© SilverTests.ru · Кодирование информации · §6 Самоподобные строки
Печать