線性基
我在學這個的時候不明白基是一個什麼東西,然後我想了很久沒法理解究竟什麼叫做線性基,千萬不要理解成是一個序列選一些數使之異或和最大。。
首先
你得有一些高一數學基礎比如說向量,我們可以任意定義兩條單位長度的向量,這兩條能夠成該平面直角座標系的所有向量,這兩條向量稱之爲基底。
那麼,線性基差不多也是這個意思,
線性基的定義
:
(百度百科)
通過原集合S的某一個最小子集S1使得S1內元素相互異或得到的值域與原集合S相互異或得到的值域相同。
emm怎麼說呢,線性基能夠成這個序列所能產生的任何xor值,即線性基
類似於基底對於平面直角座標系的基底
爲什麼呢?首先我們要明白xor的一個性質
^即xor的運算符
1. ^ ^
2.如果
^
那麼
^
^
根絕這兩個性質,我們可以由任意一組下面的 來得到其他的數
我這裏用一個s數組來維護線性基
代表 位是1,且 位是該數的最高位。
類似於反着來的 (樹狀數組)
我們可以來模擬一組數據
先上代碼
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#define ll long long
using namespace std;
const int maxn=1e6+5;
const int mod=1e9+7;
ll a[maxn],sum,s[65];
void insert(ll val)
{
for(int i=60;i>=0;i--)
if (val&(1ll<<i))
if (!s[i])
{
s[i]=val;
return;
}
else val^=s[i];
}
int main()
{
ll n,j,k;
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
insert(a[i]);
ll ans=0;
for (int i=60; i>=0; i--)
if ((ans^s[i])>ans) ans^=s[i];
printf("%lld\n",ans);
return 0;
}