1. 程式人生 > 其它 >初見 | 資料結構 | 線性基

初見 | 資料結構 | 線性基

線性基淺學,圖片表意不明(

主要參考了 Menci 的線性基學習筆記

「前置知識」

一些線性基能用到的。

下文中若未特殊說明,集合均為「無符號整數集」。

「異或和」

對於集合 \(S\),將其中所有元素異或起來的結果。

「張成」

對於集合 \(S\) 的所有子集的異或和組成的集合成為 \(S\)張成,記作 \(span(S).\)

換句話說就是在 \(S\) 中選出任意多個數,其異或和的所有可能的結果組成的集合。

「線性相關」

對於一個集合 \(S\),如果存在一個元素 \(i\),使得,\(S\) 在去除這個元素後得到的集合 \(S'\) 的張成 \(span(S')\) 中包含 \(i\),即,\(i\in span(S')\)

,則稱集合 \(S\) 線性相關。

換句話說就是 \(S\) 中存在一個元素 \(i\) 可以被 \(S\) 中的其他的若干個元素異或得到。

如果不存在這樣的 \(i\),就說 \(S\) 線性無關。

一個顯然的結論是對於一個線性相關的集合 \(S\),去掉符合條件的 \(i\) 之後,\(span(S)\) 不變。

「線性基」

稱集合 \(LB\) 為集合 \(S\) 的線性基,當且僅當:

  1. \(S\in span(LB).\)

  2. \(LB\) 線性無關。

\(LB\) 中的元素個數,稱為線性基的長度。

線性基有以下的性質:

  1. \(LB\) 是極小的滿足線性基性質的集合,它的任何真子集都不可能是線性基;

  2. \(S\) 中的任意元素都可以唯一表示為 \(LB\) 中若干個元素異或起來的結果;

  3. 線性基裡任意一個子集的異或和都不為\(0.\)

「模板」

下面是模板。

「構造」

I void Insert(int x)
{
    for(int i(62);i>=0;--i)
    {
        if(x&(1<<i))
        {
            if(!p[i])
            {
                p[i]=x;
                
                Heriko;
            }
            else
                x^=p[i];
        }
    }
}

「查詢元素是否存在」

因為“\(S\) 中的任意元素都可以唯一表示為 \(LB\) 中若干個元素異或起來的結果”,所以如果一個數在不斷異或的過程中,能變成 \(0\),那就存在於集合中。

I bool Query(int x)
{
    for(int i(62);i>=0;--i)
        if(x&(1<<i))
            x^=p[i];

    Heriko !x;
}

「查詢異或最大值」

貪心即可。

I int XorMax(int x)
{
    int res(0);

    for(int i(62);i>=0;--i)
        if((res^p[i])>res)
            res^=p[i];

    Heriko res;
}

「查詢異或最小值」

貪心即可,但是要特判 \(0\),即存在 \(0\) 的時候最小值為 \(0.\)

I int XorMin(int x)
{
    if(HaveZero)
        Heriko Deltana;

    for(int i(62);i>=0;--i)
        if(p[i])
            Heriko p[i];
}

暫且就先這些,還有一個查詢第 \(k\) 大異或值的操作,因為我還沒用過所以就先不寫。

Do you like WHAT YOU SEE ?