解方程

解方程

给定一个非负整数 a,请你计算方程 a(ax)x=0 的非负整数解的数量。

其中 指按位异或。

输入格式

第一行包含整数 T,表示共有 T 组测试数据。

每组数据占一行,包含一个非负整数 a

输出格式

每组数据输出一行结果,一个整数,表示方程的非负整数解的数量。

可以证明方程的非负整数解数量总是有限的。

数据范围

3 个测试点满足 1T3
所有测试点满足 1T10000a2301

输入样例:

3
0
2
1073741823

输出样例:

1
2
1073741824

 

解题思路

  这题可以根据样例来找出规律,假设a在二进制下有t1,那么答案就是2t

  比如样例中的1073741823=(111111111111111111111111111111)2,有301,那么答案就是230=1073741824

  把题目中的等式变换一下,有ax=ax。考虑a的二进制所有位都是1的情况,那么对于x的任意一位无论是0还是1,做减法时都不会向前借位,因此任意两个位都是相互独立的。再来看一下,如果x的某一位为0,那么与a相应的位做减法后该位为1,异或运算得到的也是1。如果x的某一位为1,那么与a相应的位做减法后该位为0,异或运算得到的也是0。因此当a的所有位均为1时,x的任意一位都可以取01,因此x2t种(ta在二进制下1的位数)。

  如果a在二进制下的位数不全为1,那么从低位向高位看,如果最低位为1,那么x在最低位取0和取1在减法和异或运算后该位得到的结果是一样的。接着从a的低位往高位看,找到第一个0,此时x在这一位取0是可以的,在减法和异或运算后得到的结果都是0。如果取1,对于减法运算一定会往高位借位,即往高位数的第一个1借位,假设这一个位是第k位,此时如果x的第k0,那么借位后a的第k位变成0,做减法后得到0,而异或运算得到的结果是1a的第k位为1x的第k位为0)。而如果x的第k1,做减法后得到1,异或运算得到的结果是0a的第k位为1x的第k位为1)。因此对于a中为0的位x在该位不能填1,只能填0,而a中为1的位x在该位能填01且各个位相互独立,因此答案就是2t

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int main() {
 5     int tot;
 6     cin >> tot;
 7     while (tot--) {
 8         int n;
 9         cin >> n;
10         int cnt = 0;
11         while (n) {
12             cnt += n & 1;
13             n >>= 1;
14         }
15         cout << (1 << cnt) << '\n';
16     }
17     
18     return 0;
19 }
复制代码

 

参考资料

  AcWing 4617. 解方程(AcWing杯 - 周赛):https://www.acwing.com/video/4355/

posted @   onlyblues  阅读(165)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示