Sum of Remainders(数学题)

 

F - Sum of Remainders

Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

 

Description

Calculate the value of the sum: n mod 1 + n mod 2 + n mod 3 + ... + n mod m. As the result can be very large, you should print the value modulo 109 + 7 (the remainder when divided by 109 + 7).

The modulo operator a mod b stands for the remainder after dividing a by b. For example 10 mod 3 = 1.

Input

The only line contains two integers n, m (1 ≤ n, m ≤ 1013) — the parameters of the sum.

Output

Print integer s — the value of the required sum modulo 109 + 7.

Sample Input

Input
3 4
Output
4
Input
4 4
Output
1
Input
1 1
Output

0

 

//给你两个数n,m,问你n % 1 + n % 2 + … + n% m为几

这个题目的思路是,和为 n * m - sum ( [ n / i ] * i )  ,[ ] 是向下取整,i 从(1--- m) 

具体是:

前面的 n*m 肯定就这样了

主要是后面的 :将 [ n / i ] 相同的做一个区间,用求和公式去节省时间

i 从 1 --- sqrt (n) ;

l = n / ( i + 1 ) + 1 , r =  n / i ; // 这就是一个个的区间

比如 n = 20 , m = 20

i=1 -->  l=11, r=20   n / (11---20) 都是等于 1 

i=2 -->  l=7, r=10     n / (7---10) 都等于2

i=3 -->  l=r=6

i=4 -->  l=r=5

注意一些特殊情况,看注释

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 using namespace std;
 5 
 6 #define ll __int64
 7 const ll MOD=1e9+7;
 8 
 9 int main()
10 {
11     ll n,m;
12     scanf("%I64d%I64d",&n,&m);
13     ll ans=(n%MOD)*(m%MOD)%MOD;
14     ll temp=0,las=m+1;//记录哪些数没被减
15     m=min(n,m);//n 余大于 n 的都等于 n
16     ll nn=(ll)sqrt(n*1.0);
17     for (ll i=1;i<=nn;i++)
18     {
19         ll l = n/(i+1)+1;
20         ll r = n/i;
21 
22         r=min(r,m);//可能 r 比 m 大
23         if (l>r) continue;
24 
25         las=min(las,l);
26 
27         ll s1=l+r , s2 =(r-l+1);//这里高斯求和有个坑,要先判断哪个数可以除2,再乘
28         if (s1%2==0) s1/=2;     //直接用公式也不对,会超出ll限制
29         else s2/=2;
30         s1%=MOD;s2%=MOD;
31         s1=(s1*s2)%MOD;
32         s1=s1*i%MOD;
33         temp=(temp+s1)%MOD;
34     }
35     ans=(ans+MOD-temp)%MOD;
36     for (ll i=1;i<las;i++) //剩下的没被减得数,将n余之为0的最大整数减去
37     {
38         temp=n/i%MOD*i%MOD;
39         ans=(ans+MOD-temp)%MOD;
40     }
41     printf("%I64d\n",ans);
42 
43     return 0;
44 }
View Code

 

posted @ 2016-10-05 12:00  happy_codes  阅读(423)  评论(0编辑  收藏  举报