基准时间限制:1 秒 空间限制:131072 KB
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%k = n - n/k*k;然后前后两个分开来求前半部分为n*n,后半部分为sum(n/k*k);那么求出后半部分就很容易知道结果了,后半部分求和可以分成两个部分来求
我们考虑n/k的值在1--sqrt(n),那么当n/k=1时k的范围是n--(n/2+1)是个等差数列然后等差数列求和累加,那么循环到sqrt(n),就能求得k的范围在[sqrt(n),n]的
sum(n/k*k)的值,然后剩下的[1,sqrt(n)]直接从1循环到sqrt(n);
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<string.h> 5 #include<queue> 6 #include<math.h> 7 #include<set> 8 #include<vector> 9 #include<string.h> 10 using namespace std; 11 typedef long long LL; 12 const LL mod = 1000000007; 13 LL quick(LL n,LL m); 14 void slove(LL n); 15 int main(void) 16 { 17 LL n; 18 cin>>n; 19 slove(n); 20 return 0; 21 } 22 void slove(LL n) 23 { 24 LL ak = sqrt(1.0*n); 25 LL ac = n; 26 LL sum = 0;int i; 27 for(i = 2; i <= ak; i++) 28 { 29 LL t = n/(i); 30 t++; 31 LL cn = ac-t+1; 32 LL x = (((ac+t)%mod)*(cn%mod))%mod; 33 sum = sum + x*(LL)(i-1); 34 sum%=mod; 35 ac = t-1; 36 } 37 LL ni = quick(2,mod-2);sum = sum*ni%mod; 38 for(i = 1; i <= ac; i++) 39 { 40 sum = (sum+((n/(LL)i)%mod)*(LL)i%mod)%mod; 41 } 42 43 LL ask = (n%mod)*(n%mod)-sum%mod; 44 printf("%lld\n",(ask%mod+mod)%mod); 45 } 46 LL quick(LL n,LL m) 47 { 48 LL ak = 1; 49 n%=mod; 50 while(m) 51 { 52 if(m&1) 53 ak = ak*n%mod; 54 n = n*n%mod; 55 m>>=1; 56 } 57 return ak; 58 }