给n,求n/1+n/2+n/3+....+n/n的值
Posted yueshehanjiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了给n,求n/1+n/2+n/3+....+n/n的值相关的知识,希望对你有一定的参考价值。
给n,求n/1+n/2+n/3+…+n/n的值
首先,n最大范围1e9,暴力肯定超时
那么先看一段代码
#include<bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define re register int
typedef long long ll ;
using namespace std;
const int N = 1e6 + 10 , M = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
int main()
{
int n ;
cin >> n ;
for(int l = 1 , r ; l <= n ; l = r + 1)
{
r = n / (n / l) ;
printf("%d %d %d\\n",n/l,l,r) ;
}
return 0;
}
我们输入100 可以得到的结果是
n / l l r
100 1 1
50 2 2
33 3 3
25 4 4
20 5 5
16 6 6
14 7 7
12 8 8
11 9 9
10 10 10
9 11 11
8 12 12
7 13 14
6 15 16
5 17 20
4 21 25
3 26 33
2 34 50
1 51 100
那么,很明显从51到100中的数,除n都等于1
从34到50中的数,除n都等于2
以此类推从l到r中的数,除n都等于n/l
那么每次给出左端点,如何求右端点
考虑一下假设左端点为l
那么 n / (n / l ) 是不是就是右端点
因为c++默认下取整
在算出当前区间的左右端点的情况下
下一个区间的左端点就是上一个区间的右端点+1
那么答案就是(r - l + 1) * (n / l )
时间复杂度分析
#include<bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define re register int
typedef long long ll ;
using namespace std;
const int N = 1e6 + 10 , M = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
int main()
{
int n ;
cin >> n ;
int cnt = 0 ;
for(int l = 1 , r ; l <= n ; l = r + 1)
{
r = n / (n / l) ;
cnt ++ ;
}
cout << cnt << endl;
return 0;
}
我们分别输入100 10000 1000000 100000000
可以得到结果是 19 199 1999 19999
因此时间复杂度为 2sqrt(n)
最后ac代码
#include<bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define re register int
typedef long long ll ;
using namespace std;
const int N = 1e6 + 10 , M = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
int main()
{
int t ;
cin >> t ;
while(t--)
{
int n ;
cin >> n ;
ll res = 0 ;
for(int l = 1 , r ; l <= n ; l = r + 1)
{
r = n / (n / l) ;
res += (r - l + 1 ) * (n / l );
}
cout << res << endl;
}
return 0;
}
以上是关于给n,求n/1+n/2+n/3+....+n/n的值的主要内容,如果未能解决你的问题,请参考以下文章