Helgui's blog

By Helgui, history, 6 years ago, In Russian

Привет, Codeforces!

Кратко о том, что здесь происходит: сначала мы находим задачку, решаем её формулой включений-исключений, удивляемся возникшей функции Мёбиуса, узнаём об обобщённой формуле обращения Мёбиуса, выводим решение задачи напрямую с помощью неё, а заодно решаем более общую задачу. Если это кажется Вам интересным, то продолжим.

//Вместо картинки
#include <A>
#include <B>
#include <C>
#exclude <AB>
#exclude <AC>
#exclude <BC>
#include <ABC>

Недавно наткнулся на задачу 803F - Coprime Subsequences, в которой требуется найти число таких подпоследовательностей массива, что НОД всех чисел подпоследовательности равен 1. Задача несложная и решается на основе следующих соображений:

  1. Число непустых подпоследовательностей массива из k элементов равно 2k - 1
  2. Задачу можно переформулировать так: необходимо отыскать количество подпоследовательностей, для которых не найдется простого числа, делящего все элементы
  3. Пусть P — множество простых чисел до 105, а d(x) — число подпоследовательностей, каждый элемент которых кратен x. Если m(x) — число элементов массива, кратных x, то в соответствии с п. 1 имеем d(x) = 2m(x) - 1
  4. Если взаимнопростые p и q делят x, то p·q также делит x.

Скомбинировав вышесказанное и применив принцип включений-исключений получаем, что

считая, что произведение пустого множества равно 1. Итак, мы получили сумму из 2|P| слагаемых, но большая часть из них не вносит вклада в ответ, т.к. соответствующее произведение превышает 105. Можно непосредственно нагенерить нужные произведения, а можно просто пройтись по [1;105], отбрасывая числа, не являющиеся произведениями простых (например, это можно проверить за логарифм, посчитав наименьший простой делитель в решете). Я воспользовался 2-м вариантом, и у меня получилось такое решение: 33406195

Сдав задачу, я заглянул в разбор, а там

Я посмотрел в код. Посмотрел в разбор. И снова в код. Функция sign(x), возвращающая знак слагаемого, как раз и есть функция Мёбиуса:

Функция int sign(int x)
Почему во включениях-исключениях всплыла функция Мёбиуса? Совпадение? Не думаю.

И тут я пошёл читать про функцию Мёбиуса. Я узнал про формулу обращения Мёбиуса, про обобщённую функцию Мёбиуса для частично упорядоченных множеств (под спойлером). Оказалось, что для обобщённой функции Мёбиуса также справедлива формула обращения, и формула включений-исключений является её частным случаем.

Обобщенный Мёбиус (кому лень идти на википедию)

Заметив, что формула ответа напоминает обращение Мёбиуса, я попробовал вывести решение напрямую с помощью него и вот, что получилось.

Рассмотрим множество A = [1;105] c отношением кратности (именно кратности, а не делимости) в качестве отношения порядка, т.е. (строгий вариант ). Например, , а . Пусть g(x) — число подпоследовательностей, НОД которых равен x. Обозначенная ранее величина d(x) выражается суммой g(y) по всем y кратным x, т.е.

Пусть μA(x, y) — функция Мёбиуса для A, тогда, применяя обобщенную формулу обращения Мёбиуса, получаем

Тогда ответ на задачу равен

Если показать, что μA(x, 1) = μ(x), то мы получим приведенную ранее формулу для ответа на задачу. Покажем это, сведя наш случай к известному, для которого доказан аналогичный результат.

Доказательство

Таким образом, мы получили решение задачи, не прибегая к включениям-исключениям, а применив обобщенную формулу обращения Мёбиуса. В качестве бонуса имеем решение более общей задачи:

  • Vote: I like it
  • +55
  • Vote: I do not like it