【题解】最大奇约数

题目

题目描述

定义函数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<=N<=10^9

样例

样例输入

7

样例输出

21

数据范围与提示

样例说明

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


以上是题目


题解

奇数的最大约数是自身, 偶数的最大奇约数是除所有偶因子之后的那个奇数。所以直观的思路就是挨个遍历一遍加起来
但是,这种思路保守估计复杂度为O(n),因为我也搞不清楚这种思路的复杂度到底怎么算,而n的范围是10^9,想都不用想
会TLE

于是有人想到了用记忆化,但你想想你写一个:

int Memory[1000000005];

你心里就不慌吗,先不管你慌不慌,反正编译器是肯定吃不消的,于是…

我们的O(logn)的5G超快正解来了

设sum(i) = f(1) + f(2) + … + f(i);

求sum(i)的过程中,如果i 为奇数可以直接求,就是 i 本身,即f(i) = i。

问题就是求所有f(i), i为偶数的和。

因为是最大奇约数,所以f(2k) = f(k),所以f(2) + f(4) + … + f(2k) = f(1) + f(2) + … + f(k);

所以

avatar

而1+3+5+…+(n-1)等于(n/2)^2

证明

(一):代数法

1+3+5+…+(n-1)共有(n-1-1)/2+1

而高斯告诉我们:1+3+5+…+(n-1)=(首项+末项)*项数/2

代入公式即得:1+3+5+…+(n-1)={[1+(n-1)]*[(n-1-1)/2+1]}/2

化简得:1+3+5+…+(n-1)=(n/2)^2

得证

(二):几何法

我们把1表示为如图所示面积为1的小正方形
avatar

把3表示为如图所示面积为3的图形
avatar

把5表示为如图所示面积为5的图形
avatar


以此类推,最后把他们拼接起来,得到一个正方形
avatar

它可以表示为1+3+5+…+(n-1),也可以表示为边长的平方,而边长就等于n/2

所以1+3+5+…+(n-1)=(n/2)^2

最后贴上代码

#include<iostream>
#include<cstdio>
using namespace std;
long long sum(long long n){
    if(n==1){
        return 1;
    }
    if(n%2==0){
        return sum(n/2)+n*n/4;
    }
    else{
        return sum(n-1)+n; 
    }
}
int main(){
	int n;
	scanf("%d",&n);
	printf("%lld",sum(n));
return 0;
}

猜你喜欢

转载自blog.csdn.net/tanfuwen_/article/details/106819538