線性基,是可以刪除的。
維護哪些數在線性基中,以及維護的每個線性基如何用它們表示,還有不在線性基中的數如何表示。
刪除一個數\(x\)時,分類討論。
若這個數不在線性基中,直接刪除即可。
否則,就要消除它的影響。
找到一個不在線性基中,且需要\(x\)來表示的數\(y\)。
如果找到了,那么把\(y\)加入線性基中,\(x\)可以用\(y\)和其它的基表示。
把它代入到其他的數的表示內,就可以消去這個\(x\)。
其中,按照最高位維護的線性基無需改變,但它們的表示方法需要改變。
如果找不到,那么說明基的大小應當減一。
找到維護的線性基內,最小的需要用\(x\)表示的數\(z\)。
然后,把維護的其他的需要用\(x\)表示的線性基都異或上\(z\)。這樣就消除了\(x\)的影響。
\(z\)這個基就沒有了,同時因為它是最小的,所以其他維護的基的最高位都不會改變。
void insert(int i,bitset<1000> &bi,int s)
{
ij[i]=false;bs[i]=0;
for(int j=s-1;j>=0;j--)
{
if(bi[j])
{
if(ji[j]==0)
{
ji[j]=bi;r+=1;ij[i]=true;
bj[j]=bs[i];bj[j][i]=true;
break;
}
else
{
bi^=ji[j];
bs[i]^=bj[j];
}
}
}
}
void del(int i,int n,int m)
{
if(!ij[i])return;
int z=-1;
for(int x=0;x<n;x++)
{
if(!ij[x]&&bs[x][i])
{
z=x;
break;
}
}
if(z!=-1)
{
ij[z]=true;
bitset<1000> t=bs[z];
t[z]=true;
for(int x=0;x<n;x++)
{
if(bs[x][i])
bs[x]^=t;
}
for(int x=0;x<m;x++)
{
if(ji[x]!=0&&bj[x][i])
bj[x]^=t;
}
return;
}
else
{
for(int x=0;x<m;x++)
{
if(ji[x]!=0&&bj[x][i])
{
z=x;
break;
}
}
bitset<1000> t=bj[z],o=ji[z];
ji[z]=0;r-=1;
for(int x=0;x<m;x++)
{
if(ji[x]!=0&&bj[x][i])
{
ji[x]^=o;
bj[x]^=t;
}
}
}
}