求∑i=1nf(i) \sum_{i=1}^n f(i) i=1∑nf(i)
f(i)为因数之和,所以可以转化为
∑i=1n∑d∣id\sum_{i=1}^n\sum_{d|i}d i=1∑nd∣i∑d
因为f(i)不包括i本身,所以最后要减去
n∗(n+1)2\frac {n*(n+1)} 22n∗(n+1)
我们主要看前面
改变枚举对象为d,转化为
∑d=1nd⌊nd⌋\sum_{d=1} ^n d\lfloor\frac n d\rfloord=1∑nd⌊dn⌋
数论分块即可
因为有一个d,所以比较怪异
令r=n/(n/l)
我们考虑在x∈(l,r)中⌊nx⌋\lfloor\frac n x\rfloor⌊xn⌋为定值都为m,所以每一段为∑x=lrmx\sum_{x=l}^r mxx=l∑rmx
在分块的时候变成⌊nl⌋∗(l+r)∗(r−l+1)/2\lfloor\frac n l \rfloor* (l+r)*(r-l+1)/2⌊ln⌋∗(l+r)∗(r−l+1)/2就好
代码
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
ll n;
ll f(ll x)
{
ll ans=0;
for(ll l=1,r;l<=x;l=r+1)
{
r=x/(x/l);
ans+=(r-l+1)*(l+r)*(x/l)/2;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
cout<<(f(n)-((n+1)*n)/2)<<endl;
}
}