系列trick - bitmask
作者:互联网
系列trick - bitmask
拆位
主体思想:位之间不影响,把每一位拆开来考虑贡献,转化成非常容易考虑的 0/1。
首先要看出来位之间不影响,当题目涉及二进制运算时应当首先注意的就是这一点。
例题有一堆,这里拿最近做的一个举例子
CF1327F:这题给你若干个限制 \((l,r,x)\),表示 \([l,r]\) 的区间AND和必须是 \(x\);求满足条件长度为 \(n\),并且每个数都 \(<2^k\) 的序列数。
显然位独立,然后相当于限制区间都是 \(1\) 或者区间至少有一个是 \(0\)。随便 dp 一下就可以计数了。然后把每一位的答案乘起来,就是最后的答案了。
例2:整数 求逆序对的神秘方法
从高到低来考虑,如果当前的位就能比较出结果(相当于一个01序列求逆序对, 开个cnt记一下即可),就计入答案;当前位相同的用分治的技巧分成两部分解决。复杂度是值域的 \(\log\),乘以 \(n\) 。
它看起来很傻逼,但是由于它拆位,支持更多操作(详见分治那篇里的题)
位运算优化(点少的)图操作
点少:指 \(2^n\times ...\) 可以通过。
主体思想:用位运算加速图的操作,以优化掉复杂度 卡常
讲道理,其实纸面复杂度没有被优化,只是把一些耗时间的操作交给 cpu 来搞了,比如把一个 \(O(n)\) 的操作用位运算做掉,变成 “\(O(1)\)”
有啥用呢?\(n=24,25\) 的时候,\(2^n\) 的复杂度多一个 \(n\) 都是过不去的。
比如,可以把每个点的出边压成一个集合,然后每次把当前的状态跟它或以下,就可以实现搜索中的 “扩展”。
例1 判断强连通,\(n\le 24\) :这个题 的 \(60\) 分,\(O(2^n n)\) 的做法。
例2 例1的100分 (这个还涉及到筛法,见下一个trick)
位筛
主体思想:筛法,定义域为二进制压缩的集合
这类问题时间复杂度通常会有保证:每个集合只会被筛一次,复杂度是 \(O(2^n)\)
标签:系列,运算,复杂度,trick,bitmask,点少,拆位 来源: https://www.cnblogs.com/LightningUZ/p/14259120.html