关于 bitset 的一些题目

参考

bitset

bitset<MAXN> b;
b.any()    // b中是否存在置为1的二进制位。
b.none()   // b中是否不存在置为1的二进制位。
b.count()  // b中置为1的二进制位的个数。
b.size()   // b中二进制位数的个数。
b[pos]     // 访问b中在pos处二进制位。
b.test(pos) // b中在pos处的二进制位置为1么?
b.set()    // 把b中全部二进制位都置为1。
b.set(pos) // 把b中在pos处的二进制位置为1。
b.reset()  // 把b中全部二进制位都置为0。
b.reset(pos) // 把b中在pos处的二进制位置置为0。
b.flip()  // 把b中全部二进制位逐位取反。
b.flip(pos)  // 把b中在pos处的二进制位取反。
b.to_ullong() // 返回一个有相同二进制位的 unsigned long long 类型的值。

想法

通常先考虑题目的暴力作法,若是复杂度有 \(1e9\) ,这时候就可能考虑 \(bitset\) 优化,通常题目中的关系相似于能不能?是否是?这种,或者能够用 \(bitset\) 优化 \(DP\)(背包 \(DP\) 比较多,或者用于记录路径之类) ,一个有趣的应用是对于一些字符串问题,字符串长度不长,可是动态更新,询问次数不少的状况,能够维护 \(bitset\) 进行快速求解。php

题目

  • Triatrip
  • Bipartite Graph 显然二分图两边点数要尽量相同,考虑 01背包DP, \(bitset\) 优化,二进制位 \(i\) 表示是否能构成点数量为 \(i\) 的一边。
  • Addition on Segments 先进行相似于线段树的更新操做,而后用 \(bitset\) 加速状态转移。
  • Explosion \(bitset\) 加速传递闭包的计算。
  • Eighty seven 考虑前缀后缀,开两个 \(bitset\) 类型的 \(DP\) 数组,之前缀为例,\(dp[i][j][k]\) 表示到第 \(i\) 个数,必定不选 \(j\) 这个位置上的数,选了 \(k\) 个数时全部可能的和(二进制位为\(1\)表示有这样的和)。对于后缀的数组,若是二进制位 \(i\) 上的数字为\(1\),可修改成 \(bit[87-i]=1\),那么对于询问,枚举 \(k\) ,将前缀后缀按位与,检查是否有二进制位为\(1\)
  • Price List Strike Back
  • Judgement 01背包 \(DP\)\(bitset\) 记录路径。
  • 带可选字符的多字符串匹配 \(bitset\) 加速匹配。预处理不一样字符可能出现的集合,若是到主串上的第 \(i\) 个字符,有 \(bit[j]=1\) 表示已经匹配了长度为 \(j\) 的模板串。\(bit<<1\) 等价于加入一个新的字符,利用前面的预处理能够判断转移是否合法(按位与),若不合法则对应的二进制位会变成 \(0\)
  • The Values You Can Make 背包 \(DP\)
  • La Vie en rose \(bitset\) 优化字符串匹配。
  • Nearest Maintenance Point 在最短路搜索的过程当中使用 \(bitset\) 记录信息,表示从哪些点到当前点有最短路。
  • Rikka with Candies 离线查询。因为 \(a \% b = k\)\(0\leq k < b\),咱们能够从大到小枚举这个 \(k\) ,统计答案,而后更新 \(bitset\)\(k\) 的倍数。
相关文章
相关标签/搜索