[错题][题解]小沙的数数

29 篇文章 0 订阅
10 篇文章 0 订阅

题目

题目描述

有一个a数组,我们已知他的长度为n,a[+]的和为m,请问如果我们想要a[⊕]的值最大,数组a在满足a[+]=m时有多少种情况
我们定义a[+]指 a 1 + a 2 . . . . a n a_1+a_2....a_n a1+a2....an的值,所以a[⊕]指 a 1 ⊕ a 2 ⊕ a 3 . . . . a n a_1⊕a_2⊕a_3....a_n a1a2a3....an的值
其中a数组全部都为非负整数。
答案对1e9+7取模

输入描述

输入两个整数 1 ≤ n ≤ 1 0 18 1\leq n \leq 10^{18} 1n1018 0 ≤ m ≤ 1 0 18 0\leq m \leq 10^{18} 0m1018

输出描述

输出一个整数表示方案数

题解

def main():
	MOD = int(1e9 + 7)
	n,m = map(int,input().split())
	n %= MOD
	res = 1
	while m:
		if m & 1: res = res * n % MOD
		m >>= 1
	print(res)
if __name__ == '__main__':
	main()

这道题代码像是脑筋急转弯,代码非常短,但是可能会被绕进去。

假设输入 n = 4 n = 4 n=4 m = 14 m = 14 m=14
那么m的二进制表示为1110。

如果要使 a [ ⊕ ] a[⊕] a[]尽可能大,那么最好的选择就是使二进制位上的一不会被抵消为0,也就是说,确保 a [ ⊕ ] a[⊕] a[]的结果为m,便是想要的方案。

例如,对于 m = 14 m = 14 m=14,二进制为1110。
可以划分为:

  • 1110 + 0 + 0 + 0
  • 1100 + 10 + 0 + 0
  • 1010 + 100 + 0 + 0
  • 110 + 1000 + 0 + 0
  • 1000 + 100 + 10 + 0

以上五种情况的全排列方案数的总和。

而这里的错误解题方向便是通过排列组合计算推出公式,计算出结果。
因为这道题的数据范围实在太大,所以这个方法很难行得通。

而通过进一步的观察,这个里实际上可以以非排列组合的方式更加巧妙地推出公式。
如下。

可以发现,二进制数m中“1”的数量和每一个方案中“1”的数量是完全一致的。
而每一个方案之间的差别仅仅是"1"的位置的差别。

并且,每一位“1”可以相互独立,互不影响,像一个个独立的人一样,可以自由地选择去到任意一间房间。

因此可以把问题进一步转化如下。
在这里插入图片描述

如图,有 x x x个人,和n间房间,一间房间可以容纳任意数量的人。现在每一个任意去一间房间,有多少种进入房间的方案?

注:其中的x对应的便是原题中 m m m的二进制数中“1”的数量

于是本题就不言而喻了。


题目链接

原创不易,感谢支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wingaso

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值