F(n) = (n % 1) + (n % 2) + (n % 3) + ...... (n % n)。其中%表示Mod,也就是余数。
例如F(6) = 6 % 1 + 6 % 2 + 6 % 3 + 6 % 4 + 6 % 5 + 6 % 6 = 0 + 0 + 0 + 2 + 1 + 0 = 3。
给出n,计算F(n), 由于结果很大,输出Mod 1000000007的结果即可。
Input
输入1个数N(2 <= N <= 10^12)。
Output
输出F(n) Mod 1000000007的结果。
Input示例
6
Output示例
3
我们知道余数m= n-n/i*i;
显然sigma(i)n/i,n/i的值在一定区间内是不变的
于是根据n/i做公比,分块搞搞等比数列求和就好啦~,复杂度O(sqrt(n))。
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define INF 0x3f3f3f3f
#define LL long long
#define bug cout<<"bug\n"
using namespace std;
const int MAXN = 1e7+7;
const int MAXM = 1e9+7;
const long long MOD = 1e9+7;
// m= n-n/i*i;
long long quick_pow(long long a,long long n)
{
long long ans=1;
while(n)
{
if(n&1)ans=ans*a%MOD,ans%=MOD;
a=a*a%MOD;
n>>=1;
}
return ans;
}
long long inv(long long a)
{
return quick_pow(a,MOD-2);
}
int main()
{
long long n;
long long ans=0;
long long c=inv(2);
while(~scanf("%I64d",&n))
{
for(long long i=1,j; i<=n; i=j+1)
{
j=n/(n/i);
long long d=(n/i)%MOD;
long long m=(j-i+1)%MOD;
long long a1=(n-d*i)%MOD;
ans+=(m*a1-(m-1)%MOD*m%MOD*c%MOD*d%MOD)%MOD;
ans%=MOD;
// cout<<i<<"->"<<j<<"="<<ans<<endl;
}
cout<<ans<<endl;
}
return 0;
}
//995921
//87448611