最大的奇约数

来源:互联网 发布:杭州宏杉科技 知乎 编辑:程序博客网 时间:2024/05/01 18:46

题目

小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题: 定义函数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
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。

解答

本来这个题挺简单的,分分钟写出来:

#include<iostream>using namespace std;int f(int n){    while(n%2==0)        n = n/2;    return n;}int main(){    int N;    cin>>N;    int res = 0;    for(int i=0;i<N;i++){        res = res+f(i);    }    cout<<res;}

结果时间复杂度有点大。。。没通过。
只能换一种方法,奇数的最大奇因数是其本身,所以奇书直接相加,把N除以2,得到的1-N/2即是原先的每个偶数除以2得到的序列。再用同样的方法进行处理。
比如1 2 3 4 5 6 7 8 9 10
即n=10 ,此时奇数有1 3 5 7 9 我们把这几个奇数相加然后n/2
得到第二轮序列序列 1 2 3 4 5 分别对应上次的2 4 6 8 10 五个偶数。
求和时用等差求和公式,注意n为偶数时,n/2=(n+1)/2

#include<iostream>using namespace std;int main(){    long long N;    cin>>N;    long long res = 0;    for(long long i=N;i>0;i=i/2){        res = (((i+1)/2)*((i+1)/2))+res;    }    cout<<res;}
0 0
原创粉丝点击