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

posted @ 2024-03-03 18:35  _KidA  阅读(10)  评论(0)    收藏  举报