对于每个数求除1和本身的约数和,然后求前n个数的所有这种约数的和;
思路:
首先可以知道对于约数考虑就好了,
对于1-n的约数,n/2-1(减1是因为2不算啊)就是约数为2出现过的次数
如果n不是很大,那么直接sum就好了;
但是这里n很大,所以搞sqrt(n),对于>sqrt(n)的约数,也就是对于q=n/i,比如n=100,n/7=12,
很明显[10,12]所有的数都可以乘以7,而且满足<=n,所以[10,12]都是前N个里面的约数;
考虑不要重复,比如100的时候sqrt(100)=10,所以每次加上[sqrt(n)+1,n/i] //这里自己注意就好了,讲的也不是这么绝对;
#include <bits/stdc++.h> using namespace std; typedef long long LL; int main() { LL n; LL ans,m; int T,cas=1; scanf("%d",&T); while(T--) { LL q,p; scanf("%lld",&n); ans=0; m=(LL)sqrt(n); for(LL i=2;i<=m;i++) { q=n/i; ans=ans+(q-1)*i; p=m+1; if(p>q) continue; ans=ans+(q-p+1)*(q+p)/2; } printf("Case %d: %lld ",cas++,ans); } return 0; }