Skip to content

Commit

Permalink
Update 位运算.md
Browse files Browse the repository at this point in the history
新增枚举集合技巧
  • Loading branch information
CurryWOE authored Oct 30, 2023
1 parent 7fe2ab1 commit 3a639bf
Showing 1 changed file with 20 additions and 6 deletions.
26 changes: 20 additions & 6 deletions docs/Base/位运算.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
## 常用内建函数
利用底层硬件,速度非常快,有些毒瘤题目甚至必须用才能过
# 位运算
$a+b=(a\oplus b)+((a\&b)<<1)$ ,把异或看成不进位的加法,与看成计算进位,左移一下加上去,刚好是和

位运算题目通常按照每一位拆开来,分别计算贡献,再加起来

int lowbit(int x){return x&(-x);} 返回最低位的1,的2的幂

__lg $O(1)$ 求 $\log_2x$ ,比 log2 快
# 内建函数
1. int __builtin_ffs(int x) :返回 x 的二进制末尾最后一个 1 的位置,位置的编号从 1 开始(最低位编号为 1 )。当 x 为 0 时返回 0 。

2. int __builtin_clz(unsigned int x) :返回 x 的二进制的前导 0 的个数。当 x 为 0 时,结果未定义。
Expand All @@ -14,10 +20,18 @@
6. int __builtin_parity(unsigned int x) :判断 x 的二进制中 1 的个数的奇偶性。

这些函数都可以在函数名末尾添加 ll (如 __builtin_popcountll )来使参数类型变为 ( unsigned ) long long (返回值仍然是 int 类型)。
## 一些公式
$a+b=(a^b)+((a&b)<<1)$

把异或看成不进位的加法,与看成只有进位的加法,与结果左移一位和异或结果相加,自然就是加法结果。在一些涉及异或的题目需要这个公式。
# 各种枚举集合
```cpp
for(int i=mask;i;i=(i-1)&mask)//枚举子集,O(2^{popcount}),没有考虑0,如果需要则特判
for(int i=0;i<(1<<n);++i)for(int j=i;j;j=(j-1)&i)//枚举每个子集的子集,O(3^n)
for(int i=mask;i<MAX;i=(i+1)|mask)//枚举超集,O(2^{TotalDigit-popcount})
for(int i=(1<<k)-1;i<(1<<n);){//枚举所有大小为k的子集,k=0需特判
//具体操作
int x=i&-i;
int y=i+x;
i=((i&~y)/x>>1)|y;
}
```

---
[讲课链接](https://www.bilibili.com/video/BV1z8411K7Dz/?spm_id_from=333.999.0.0&vd_source=57a1e2bae1f3574849d8f90b75cb25a2)

0 comments on commit 3a639bf

Please sign in to comment.