题目地址:http://lightoj.com/volume_showproblem.php?problem=1245
以n=12 为例
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
n/i | 12 | 6 | 4 | 3 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 1 |
[n/i]只有2√n个不同的解(按住Alt键,41420可以按出√)
先求出前√n项:即n/1+n/2+…+n/√n 共有√n个式子,后面每一项的值小于√n,所以只有2√n个不同的解。
那么n/1+n/2+…+n/n就是由2√n个n/i值相等的块组成的,并且每一个块的最后一个数字r为n/(n/i) ,i为这一个块内的任意数字;那么下一个块的第一个数字就是n/(n/i)+1,即r+1。我们只需要知道一个块有多少的数字和块n/i的值,二者相乘再累加即可。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
int main()
{
int t,ans;
int n;
long long sum;
ans=1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
sum=0;
printf("Case %d: ",ans);
long long r,l;
for(l=1;l<=n;l=r+1)///本题n最大为2e31-1,当r为2e31-1时,加一会变成-2e31 0111 .... 1111->1111 .... 1111
{
r=n/(n/l);
sum+=(r-l+1)*(n/l);
}
// printf("%d\n",l);
printf("%lld\n",sum);
ans++;
}
return 0;
}