【模板】线性基模板

数学太差,直接线性基当数据结构用orz 表示数集[1,2^k-1] 表示一个异或集合 可以说是将原数集压缩 性质:(直接抄的orz,虽然也不是特别懂) 1.设线性基的异或集合中不存在0。 2.线性基的异或集合中每个元素的异或方案唯一,其实这个跟性质1是等价的。 3.线性基二进制最高位互不相同。 4.如果线性基是满的,它的异或集合为[1,2n1][1,2n1]。 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;
}
主要某道题急着要用线性基,等有时间认真学一波线性基。
posted @ 2018-07-12 11:08  Newuser233  阅读(6)  评论(0)    收藏  举报