对于若干元素a[]维护其线性基
对于每个数还要维护它是由什么组成的。
添加
添加一个数x
从高位向低位枚举,如果对应的位存在线性基,那么就抑或上这个,如果到了一个位使得不能被消掉,那么直接加到这位上。
如果最后变成了零向量,那就存起来(也要存储它是由哪些数组成的)。
删除
要删除一个数a[i]
首先在零向量中找到一个包含这个a[i]的数,然后对于其他所有包含a[i]的数直接将它维护的id抑或上找到的这个的id,然后删掉当前的
如果没有,就要找一个最低位的包含a[i]的数,对于其他数消除影响。
Code
void add(){
bool bz=0;
fo(i,0,n+ml)
if (nv[i]){
if (!s[i][i]){
s[i]=nv;
id[i]=nid;
bz=1;
break;
}
nv=nv^s[i];
nid=nid^id[i];
}
if (!bz)
s0[++k0]=nid;
}
void del(int w){
int x=0;
fd(i,k0,1)if (s0[i][w]){x=i;break;}
if (x){
fo(i,0,n+ml)
if (id[i][w])id[i]=id[i]^s0[x];
fo(i,1,x-1)
if (s0[i][w])s0[i]=s0[i]^s0[x];
fo(i,x,k0-1)s0[i]=s0[i+1];
k0--;
return;
}
x=-1;
fd(i,n+ml,0)
if (id[i][w]){x=i;break;}
if (x>-1){
fo(i,0,x-1)
if (id[i][w]){
id[i]=id[i]^id[x];
s[i]=s[i]^s[x];
}
s[x]=n0;
id[x]=n0;
}
}