【模板】线性基模板
数学太差,直接线性基当数据结构用orz
表示数集[1,2^k-1] 表示一个异或集合
可以说是将原数集压缩
性质:(直接抄的orz,虽然也不是特别懂)
1.设线性基的异或集合中不存在0。
2.线性基的异或集合中每个元素的异或方案唯一,其实这个跟性质1是等价的。
3.线性基二进制最高位互不相同。
4.如果线性基是满的,它的异或集合为[1,2n−1]。
5.线性基中元素互相异或,异或集合不变。
1插入
插入某数,从高位到低位扫其二进制位上为1的数,扫到某位,这位上位0直接修改值为这个数,否则这个数与这个位上的值异或。最后结果要么为0,要么被加入了线性基void insert(int x)
{
for(int i=31;i>=0;i++)
{
if((x&(1<<i))
{
if(!a[i]) { a[i]=x; break; }
else x^=a[i];
}
}
}
2合并
暴力一个位一个位合并xxj merge(const xxj &n1,const xxj &n2)
{
xxj ans = n1;
for(int i=0;i<=31;i++)
{
if(n2.a[i])
ans.insert(n2.a[i]);
}
return ans;
}
3查询最大值
从高位一个一个异或,如果可以使ans异或某位后变大就异或一下。int query_max()
{
int ans =0;
for(int i=31;i>=0;i--)
{
if((ans^(a[i]))>ans)
ans^=a[i];
}
return ans;
}
4查询最小值
从最低位开始扫,扫到的第一个数int query_min(int i=0;i<=60;i++)
{
for(int i=0;i<=31;i++)
{
if(a[i]) return a[i];
}
return 0;
}
主要某道题急着要用线性基,等有时间认真学一波线性基。

浙公网安备 33010602011771号