Living-Dream 系列笔记 第29期
本期主要讲解位运算。
一些 Trick
- 
不要这样写: for(int i=0;i<=s.size()-1;i++) //do something here因为如果 \(s\) 是空串,则 s.size()返回 \(0\),\(0-1\) 应 \(=-1\),而因为s.size()是 \(\text{unsigned int}\) 类型,存储不了负数,因此爆炸。改成 i<s.size()就好了。
- 
\(x\) 进制转 \(y\) 进制,若数据太大,不要先想着用高精,尝试采用 \(2\) 进制作为跳板即可。 
T1
知周所众,\(\text{int}\) 占 \(32 \ \text{bit}\)。
因此对于本题,我们直接输出 (a<<16)+(a>>16) 即可(\(a\) 为输入的数),这也就是实现了将 \(a\) 的左 \(16\) 位与右 \(16\) 位交换。
然而 \(\text{int}\) 存不下,那么开 \(\text{long long}\)!
结果 \(\color{Red}{\text{WA} \ 30 \text{pts}}\)。
为什么呢?

我们发现,因为 \(\text{long long}\) 占 \(64 \ \text{bit}\),即有 \(4\) 个 \(16 \ \text{bit}\)。
而原数右移 \(16\) 位之后,我们本来期望原数的高位因为溢出而被抛弃,结果它并没有完成我们的预期,导致结果变大,因此 \(\color{Red}{\text{WA}}\)。
于是我们改用 \(\text{unsigned int}\) 就过了。
警钟撅烂。
T2
首先奇数和 \(0\) 不可能为优秀的拆分。
然后开始拆分,因为输入的数最大也只有 \(20\) 位二进制数,同时题目要求从大到小输出,因此我们从 \(20\) 循环到 \(1\),若 1<<i \(\le n\),则输出 1<<i 并令 $n \gets n \ - $ 1<<i即可。
注意如果开了 \(\text{long long}\),则需要将 1<<i 改为 1ll<<i。
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号