EduBrick
← вернуться к уроку · Уровень профи: проверь себя

E. Различные подстроки

1000 мс · 256 МБ · всё или ничего

Посчитайте количество различных непустых подстрок данной строки.

Хеши по длинам

Подстроки разной длины различны заведомо. Значит ответ - сумма по длинам LL количества различных хешей среди nL+1n - L + 1 кусков длины LL:

Long answer = 0;
for (int len = 1; len <= n; len++) {
    std::unordered_set<Long> seen;
    for (int i = 0; i + len <= n; i++) seen.insert(sub(i, i + len - 1));
    answer += seen.size();
}

Это O(n2)O(n^2) вставок в множество. При n=2000n = 2000 - два миллиона, проходит.

Чем это отличается от таблицы lcp

В прошлом занятии та же задача решалась таблицей наибольших общих префиксов - тоже O(n2)O(n^2), но по памяти O(n2)O(n^2), а здесь O(n)O(n). Разница видна как раз на границе: таблица при n=2000n = 2000 занимает 16 мегабайт, хеши - ничего.

Настоящее решение этой задачи - суффиксный массив с массивом lcp за O(nlogn)O(n \log n) или суффиксный автомат за O(n)O(n). Ограничение здесь занижено намеренно: занятие про хеши.

Про unordered_set

unordered_set от long long при плохом раскладе деградирует до квадрата из-за предсказуемой хеш-функции. Надёжнее собрать все хеши в вектор, отсортировать и посчитать различные - это O(nlogn)O(n \log n) на длину без риска.

Подробнее: «Полиномиальное хеширование».

Формат ввода

Одна строка из строчных латинских букв длиной не больше 2000.

Формат вывода

Выведите количество различных непустых подстрок.

Примеры

ввод
aaa
вывод
3
ввод
abab
вывод
7
Войдите, чтобы отправлять решения.
← Вернуться к уроку