1225 余数之和

基准时间限制: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 }

 

 
posted @ 2016-09-03 23:27  sCjTyC  阅读(267)  评论(0编辑  收藏  举报