递归之最大奇约数

题目描述:

定义函数f(x)表示x的最大奇约数,这里x表示正整数。例如,f(20) = 5,因为20的约数从小到大分别有:1, 2, 4, 5, 10, 20,其中最大的奇约数为5。

给出正整数N,求f(1)+f(2)+…+f(N)

 

输入格式:

第1行:1个正整数N

 

输出格式:

第1行:1个正整数,表示题目所求答案

 

输入样例:

7

 

输出样例:

21

 

样例说明:

f(1)+f(2)+f(3)+f(4)+f(5)+f(6)+f(7)=1+1+3+1+5+3+7=21

 

数据规模:

1<=N<=10^9

解题思路:

    一开始我的思路是这样的,就是使用枚举法,把每一个数的最大奇约数都找出来,然后对它们进行求和。但是一旦输入的n超过了几万,就超时了,所以枚举法是行不通的。之后我分析了一下问题,要计算1到n中所有最大奇约数的和,我们可以把问题拆开看,首先要分析一下对于一个数的最大奇约数该如何计算:

    如果这个数是奇数,那么最大奇约数就是这个数本身;如果这个数是偶数,这里要想到偶数乘以一个奇数一定是偶数,又因为2是最小的偶数,所以将这个数除以2就能够得到一个偶数或者是一个奇数,如果是奇数,则这个奇数就是这个数的最大公约数;否则,继续除以2,直到得到一个奇数为止。

    刚才我们说枚举法是行不通的,所以我们再次分析一下问题:

    例如,我输入一个n为奇数6,要计算a(6)=f(1)+f(2)+f(3)+f(4)+f(5)+f(6)的值,刚才我们说奇数的最大奇约数就是他本身,所以这个式子就可以分成两个部分,第一部分:f(1)+f(3)+f(5),它的值就等于1+3+5;第二部分:f(2)+f(4)+f(6),要计算偶数的最大奇约数,就要除以2,所以f(2)+f(4)+f(6)=f(1)+f(2)+f(3)=a(3),即a(6)=1+3+5+a(3);推广到n就为a(n)=(1+n)*(n/2+1)/2+a(n/2);同理,如果n为偶数,则a(n)=(1+n-1)*(n/4)+a(n/2);

参考程序:

#include<iostream>
using namespace std;
long long a(int x)
    {
        if(x==1)return 1;
        else if(x%2==0)return x*x/4+a(x/2);
        else return(1+x)*(x/2+1)/2+a(x/2);
    }
int main()
    {
        int n;
        cin>>n;
        cout<<a(n);
        return 0;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值