EduBrick

Линейный базис по XOR

Метод Гаусса над полем из двух элементов: сколько значений достижимо, какое наибольшее и выражается ли данное число.

2 мин

Множество значений, которые можно получить как XOR подмножества данных чисел, — это линейная оболочка над полем из двух элементов. У неё есть базис, и он строится за O(nlogC)O(n \log C).

Построение

Держим массив, где basis[b] — вектор, старший единичный бит которого равен bb.

void add(unsigned long long x) {
    for (int bit = 59; bit >= 0; bit--) {
        if (!(x >> bit & 1)) continue;
        if (!basis[bit]) { basis[bit] = x; return; }
        x ^= basis[bit];
    }
    // x обнулился: он выражается через уже добавленные
}

Это метод Гаусса: вместо вычитания строки — XOR, а делить не нужно вовсе, потому что коэффициенты бывают только нулём и единицей.

Что из него достаётся

вопрос ответ
сколько различных значений достижимо 2r2^r, где rr — размер базиса
наибольшее достижимое жадно по битам, см. ниже
выражается ли xx добавить xx в копию базиса: обнулился — да
kk-е по возрастанию привести базис к ступенчатому виду и взять биты kk

Почему значений ровно 2r2^r: разные подмножества базиса дают разные значения (иначе их XOR был бы нулевым, то есть базис зависим), а всего подмножеств 2r2^r.

Наибольшее значение

unsigned long long best = 0;
for (int bit = 59; bit >= 0; bit--)
    if (basis[bit] && !(best >> bit & 1)) best ^= basis[bit];

Условие !(best >> bit & 1) существенно: элемент базиса добавляем только если он улучшает ответ. Иначе XOR обнулит уже установленный бит.

Жадность верна, потому что у каждого элемента базиса свой старший бит: добавление одного не портит старшие биты, поставленные раньше.

Где встречается

  • «Сколько различных значений XOR подмножеств» — прямо размер оболочки;
  • «Максимальный XOR подмножества» — жадность выше;
  • «Максимальный XOR на отрезке массива» — базис с временными метками;
  • задачи про линейную независимость векторов над F2\mathbb{F}_2 вообще.

Заметьте разницу с задачей «максимальный XOR пары»: там подмножество состоит ровно из двух элементов, и базис не помогает — нужен бор по битам.

Смежное