最大的奇约数

本文探讨了一个关于数论的问题,即求出1到N所有数的最大奇数约数之和。介绍了两种算法实现方式,第一种直接求解但时间复杂度较高;第二种通过数学归纳法降低时间复杂度,实现高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题: 定义函数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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值