百炼成钢八总结

百炼成钢八总结

废话不多说,直接看题。

另外,现在是每道题写完当场写总结,所以每道题都有。

NKOJ 5591 果老师的位运算

假做法

思路:玄学

实现方法

  • 全部或起来。

  • 为啥呢?

  • 因为在数据特别大的时候,几乎每一位都有一个数是 \(1\),那么全部或起来和删去哪个数区别几乎是没有的。

  • 但是样例都过不了

正解

思路:前缀和

实现方法

  • 一个数组是前缀和,另一个是后缀和,通过这两个值就能求出当前的或值。

NKOJ 5610 异或序列

思路:双指针

实现方法

  • 很明显这道题是让我们看有没有进位。
  • 进位就是与运算。
  • 很遗憾与运算不符合前缀和的性质,所以与运算不能直接前缀和。
  • 好消息是加法和异或都满足,所以可以通过这俩来求与。
  • 接下来用双指针锁定区间就好了。

注意事项

  1. 不开祖宗见long long

NKOJ 2221 【位运算】"1"的数量

思路:贪心

实现方法

  • 把整个数字的二进制倒过来。

  • 然后对于每一个 \(1\) 都去看它后面是谁。

    • 如果是 \(0\) 就和 \(1\) 交换。
    • 如果是 \(1\) 就把它换到最前面去。
  • 倒序输出答案。

NKOJ 6404 [CSP-S 2019 Day1]格雷码

思路:位运算

实现方法

  • 格雷码的性质是第 \(k\) 个格雷码是 \(k\operatorname{xor}\frac{k}2\) 反过来。

注意事项

  1. unsigned long long 因为 long long 只装得下 \(2^{63}\)

NKOJ 7363 位运算

思路:位运算

实现方法

  • 注意到异或是不进位的加法,与是进位部分的一半。
  • 所以有

\[x-2y=x \operatorname{xor} y \]

  • 但是在 \(x-2y<0\)\((x-2y) \operatorname{and} y=1\) 时不成立。
  • 因为第一种小于零,第二种推倒一下就知道 \(x \operatorname{and} y\)\(x \operatorname{xor} y\) 的数位不可能有一个数位同时为 \(1\)

NKOJ 47444 异或方程

思路:位运算+组合数学

实现方法

  • 这道题中有 \(x\operatorname{xor}y\) 的结果。
  • 我们发现如果 \(x \operatorname{xor} y\) 中一定是 \(x\)\(y\) 相同的是 \(0\),不同的即 \(x\)\(0\)\(y\)\(0\)\(1\)
  • 所以实际上就是将异或结果中的 \(1\) 分配给两个数。
  • 用组合数计算即可。
  • 注意特判 \(a-b\) 是奇数以及 \(a \operatorname{and} b\)\(a \operatorname{xor} b\) 同时为 \(1\) 的情况。

NKOJ 3679 找数2

思路:位运算

实现方法

  • 由于给出了异或值,只需要把它分解为两个完整的数。
  • 通过 lowbit 得到异或的第一个 \(1\)
  • 看输入的每一个数能不能和它与成 \(0\)
  • 如果能,就分到第一个数。
  • 不能就分到第二个数。
  • 最后出现偶数次的还是会被抵消掉。

注意事项

  1. 不要用 bits 或者 iostream!会 MLE

NKOJ 3671 最大异或

思路:位运算

实现方法

  • \(l\)\(r\) 范围内,能异或的最大值应该是 \(2^x-1\) 唯一问题是不知道 \(x\) 是多少。
  • 由于 \(x\) 要越大越好,所以直接去找 \(l\)\(r\) 之间的极限,可以直接将 \(l\)\(r\) 异或,然后看有多少位。

注意事项

  1. 记住 1<<xint 范围内,要么用 pow() 要么变成 1<<xLL

NKOJ 3680 找数3

思路:位运算

实现方法

  • 这道题实际上和 NKOJ3679 差不多。
  • 我们需要提前把 \(1\sim n\) 的异或值求出来。
  • 然后和输入值异或。
  • 分类的时候需要加入 \(1\sim n\) 的值。

NKOJ 3096 【伪语法基础】输入输出练习3

思路:位运算

实现方法

  • 这道题和 NKOJ3679差不多。
  • 只是题目中没有把所有数的异或值告诉我们。
  • 但是直接去求一遍是不现实的,因为数组都不能开。
  • 我们可以直接分类,但是把每种情况都算出来,相当于分64类。
  • 再去找有没有合法的。

注意事项

  1. 不要用 bits 或者 iostream!会 MLE

NKOJ 3098 【伪语法基础】输入输出练习1

思路:位运算

实现方法

NKOJ 3099 【伪语法基础】输入输出练习2

思路:位运算

实现方法

  • 考虑每个二进制位,扫一遍所有数之后

    • 如果某个二进制位上,1出现了3k+0次,则那个数的二进制的这一位是0;

    • 如果某个二进制位上,1出现了3k+1次,则那个数出现了1次,且那个数的二进制的这一位是1;

    • 如果某个二进制位上,1出现了3k+2次,则那个数出现了2次,且那个数的二进制上这一位是1。

    • 如果既有位上1出现3k+1次,又有位上1出现3k+2次,说明程序写错了;

  • n可能是3k+1或3k+2,可以帮助判断那个数的次数。

  • 开两个变量a1,a2,分别记录哪些位上1出现了3k+1和3k+2次,

  • 每次读进来一个x后做相应的更新操作。

  • a1' = (a1 ^ (a1 & x)) | (x ^ (x & (a1 | a2)))

  • a2' = (a2 ^ (a2 & x)) | (a1 & x)

注意事项

  1. 不要用 bits 或者 iostream!会 MLE
  2. 注意每次赋值的时候会盖住原来的值,所以应该把新值计算完了再赋值。

NKOJ 2223 【位运算】飞行员兄弟的冰箱

思路:DFS

实现方法

  • 这道题 DFS 的方法很多,我开始用的错误的一种,导致一直 RE
  • 一种简单的方法是将现在移动的把手的坐标作为 DFS 的值。
  • 因为将同一个位置移动两次,就会变回去,所以不会出现重复的情况,只需要考虑移动顺序。
  • 然后就是按部就班地写。
    • 如果到边界了,就判断能不能打开冰箱,如果能,就更新答案。
    • 如果没到边界,就考虑当前这个点操不操作,然后递归下去。

NKOJ 3672 "加"与"异或"

思路

  • 手玩一下样例就会发现一个奇特的规律,答案就是 \(\frac{A+B}2\)\(\frac{A-B}2\)
  • 这是为什么呢?
  • 因为异或是不进位的加法,与是加法的进位部分的一半。

\[A+B =& \text{不进位的部分}\times2+\text{进位的部分} \\ A-B =& \text{进位的部分} \]

  • 所以答案就是这样。
  • 那为什么 \(A+B\) 一定是偶数呢?
  • 因为如果 \(A+B\) 不是偶数,必然一奇一偶。
  • 但是如果 \(A\) 为奇数,那么进位的部分也就是 \(B\) 也是奇数,所以不可能。

实现方法

  • 略。

NKOJ 3673 "异或"与"或"

思路:位运算

实现方法

  • 这道题其实是在考察或和异或的性质。
  • 因为或和异或都不能凭空产生或者消除 \(1\)
  • 所以如果出现两个字符串有一个全 \(0\) 要变成 \(1\) 那就不行,否则就可以。
  • 还有如果长度不一样就想都别想了。
posted @ 2025-07-08 17:11  hsr_ray  阅读(14)  评论(0)    收藏  举报