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
思路:取余之后的数字是有规律的,比如说n=20的时候:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
0 0 2 0 0 2 6 4 2 0 9 8 7 6 5 4 3 2 1 0
每一个下划线上的几个余数都是一个等差数列(可以O(1)求出),
由下划线的第一个数字就可以求出最后一个数字,比如说7到10这一段,20/7=20/10,所以这些是一段,20/11=20/20
所以11到20是一段。假如说第一个数字是i,那么这段的最后一个就是20/(20/i),个数是20/(20/i)-i+1;
然后等差数列公式求出即可。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<string>
#include<algorithm>
#define inf 0x3f3f3f3f
#define LL long long
const LL mod=1e9+7;
using namespace std;
LL n;
LL F(LL &i)//i用引用
{
LL j=i;//开头
i=n/(n/i);//末尾
LL sum=(i-j+1)%mod;//个数
return (n%i+n%j)%mod*sum%mod*(500000004LL)%mod;//除2应该变成*500000004LL
}
int main()
{
scanf("%I64d",&n);
LL sum=0;
for(LL i=2;i<=n;i++)
{
sum+=F(i);
sum%=mod;
}
printf("%I64d\n",sum);
}