进制位技巧总结

进制位骚操作总结

lowbit

最低的为 \(1\) 的二进制位。

x&-x

利用负数二进制存储为补码的性质,我们知道负数补码是按位取反后+1,也就是原来最低的连续的一段 \(0\) 会疯狂进位直到遇到第一个 \(1\) ,和原数按位与一下就可以了。

highbit

最高的为 \(1\) 的二进制位。

预处理 \(lg2\) 数组或者使用 \(\_\_lg()\) 函数。不要用 \(log2()\) ,有 \(O(\log n)\) 的常数。

k bit状态压缩

用二进制存储集合和状态的操作大家都知道吧。显然 \(k\) 进制也是可以的。

预处理 \(k\) 的幂次可以实现快速操作。

举一个 4 bit 的例子:

struct fourbit{
	fourbit(int _x){
		x=_x;
	}
	int x;
	inline int pos(int p){
		return (x/pw[p])%4;
	}
	inline void set(int p,int k){
		x=x+(k*pw[p])-(pos(p)*pw[p]);
	}
};

集合除去

x&(x^k)

在保证 \(k\subset x\) 的情况下, 异或将 \(k\)\(x\) 中除去吗。但是如果不保证,我们可以通过与运算把误增加的元素除去。

枚举子集

for(int x=s;x;x=(x-1)&s)

这样就可以遍历 \(s\) 的子集。你发现每次子集的十进制数单调降,并且不会错过任何一个子集。因为每次把最低的 \(1\) 拉下来。需要注意的是,这个方法不会枚举到空集,需要特判一下。

通过三进制分析,枚举一个集合及其子集是 \(O(3^n)\) 的。

后续会持续更新。

posted @ 2022-07-29 16:43  cbdsopa  阅读(47)  评论(0编辑  收藏  举报