Vue2.0 與 Vue3.0 雙資料繫結對比
線性基
基本概念:
線性基的概念見:https://oi.men.ci/linear-basis-notes/
通俗的講就是給定你由N個整數構成的整數序列,你可以從中選取一些(至少一個)進行異或(\(XOR\))運算,從而得到很多不同的結果。你能將這\(N\)個整數壓縮成另一個序列,取其中的進行異或(\(XOR\)),得到的結果和之前相同,其中\(a[i]\)二進位制的最高位的\(1\)在第\(i\)位,這就是線性基。
構造線性基:
實現:將整數x插入線性基,將整數x二進位制從最高位開始往後列舉,找到最高位i的"1",判斷是否能插入bas[i],若不能將x^bas[i],然後繼續往後找。
ll bas[N]; int sz=64; bool insert(ll x){ for(int i=sz;i>=1;i--){ if((x&(1ll<<(i-1)))==0) continue; if(bas[i]) x^=bas[i]; else bas[i]=x;return true; } return false; }
高斯消元版。
bool insert(ll x){ for(int i=sz;i>=1;i--){ if((x&(1ll<<(i-1)))==0) continue; if(bas[i]){ //若如主元j已經存在,用a[j]消去x的第j位然後繼續 x^=bas[i]; continue; } for(int j=1;j<=i-1;j++){ //讓x當主元i,需要先用第j(j<i)個主元消去x的第j位 if(x&(1ll<<(j-1))) x^=bas[j]; } for(int j=i+1;j<=sz;j++){ //接著用x去消掉第j(j>i)個主元的第i位 if(bas[j]&(1ll<<(i-1))) bas[j]^=x; } bas[i]=x; return true; } return false; }
線性基相關性質
1.求任意子集xor最大值:把線性基中所有元素xor起來。
ll qryMax(){
ll ans=0;
for(int i=1;i<=sz;i++){
ans^=bas[i];
}
return ans;
}
2.求任意子集xor最小值: 等於最小的主元。
ll qryMin(){
for(int i=1;i<=sz;i++){
if(bas[i]) return bas[i];
}
}
3.查詢第k小的值:把k進行二進位制分解,把1對應位置的主元xor起來;注意這裡第0小就是0。
//快速冪
ll ksm(ll x,ll p){
ll res=1;
while(p){
if(p%2==1) res*=x;
p/=2;
x=x*x;
}
return res;
}
ll qry(ll k){
if(ok) k--; //判斷值域是否有0,有0則0為第1小
if(k<=0) return 0;
int cnt=count;//線性基大小
ll res=0;
for(int i=sz;i>=1;i--){
if(bas[i]==0) continue;
cnt--;
if(k-ksm(2,cnt)<0) continue;
res^=bas[i];//將k二進位制拆分後1的位置
k-=ksm(2,cnt);
}
if(k) return -1;//不存在的k小
else return res;
}
4.查詢x是否在值域中: 如果x能插入線性基,則x不能被當前線性基xor出來。
5.求任意子集與x進行xor的最大值:從高->低貪心,若xor上a[j]能變大就xor。
相關練習
【P3812 【模板】線性基】https://www.luogu.com.cn/problem/P3812
【P4570 [BJWC2011]元素】https://www.luogu.com.cn/problem/P4570
【acwing229 新nim遊戲】https://www.acwing.com/problem/content/231/
【acwing210 異或運算】https://www.acwing.com/problem/content/212/
【牛客練習賽76 牛牛數數】https://ac.nowcoder.com/acm/problem/214945