网易2017秋招编程题:最大奇约束 [python]

'''
[编程题] 最大的奇约数
时间限制:1秒
空间限制:32768K
小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题: 
定义函数f(x)为x最大的奇数约数,x为正整数。 例如:f(44) = 11.
现在给出一个N,需要求出 f(1) + f(2) + f(3).......f(N)
例如: N = 7 
f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。 
输入描述:
输入一个整数N (1 ≤ N ≤ 1000000000)




输出描述:
输出一个整数,即为f(1) + f(2) + f(3).......f(N)


输入例子1:
7


输出例子1:
21
'''



'''
解题思路:找规律
  一开始我很天真地老老实实用问题描述中的方法算,结果当然是超时超到妈都不认识了。后来静下心来仔细找了找规律才做出来
  我首先写出了前30个数的奇约数,并观察,发现它们似乎所有的数字都是按着1,3,5,7,9...这规律排列的
  仔细一想,便得出了如下规律:
  1~N的数字都可以看成是1,2,4,8...2^log(2,N)的奇数倍数的有序组合
  如              1         2           3           4           5           6          7           8            9
  可看出  1的1倍   2的1个  1的3倍  4的1倍   1的5倍   2的3倍 1的7倍    8的1倍   1的9倍
  找打这个规律后用计算机语言实现,可以把复杂度从O(N),下降到O(logN)
'''


'''
代码运行结果:
答案正确:恭喜!您提交的程序通过了所有的测试用例

'''


import math
N = int(input())
max_dig = int(math.log(N, 2))
sum_ = 0
for i in range(max_dig+1):
    temp = N//(2**i)
    if temp % 2:
        sum_ +=(1+temp)**2//4
    else:
        sum_ += temp**2//4

print(sum_)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值