CodeForces

来源:互联网 发布:大数据信息安全案例 编辑:程序博客网 时间:2024/06/05 02:40

易水人去,明月如霜。

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

The modulo operator a mod b stands for the remainder after dividinga by b. For example10 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 modulo109 + 7.

Example
Input
3 4
Output
4
Input
4 4
Output
1
Input
1 1
Output
0

输入n,m(1<=n,m<=10^13),求n%1+n%2+n%3+……+n%m,数据结果较大,对10^9+7取余


n%i ==> n-[n/i]*i

原式化为n*m - i=1m[n/i]i


思路1:l=n/(i+1)+1, r=n/i  ==>  n/x(l<=x<=r)的值必定等于i

举个例子n=20,m=20,现将n开根号了

i=1 ==>  l=11, r=20

i=2 ==>  l=7, r=10

i=3 ==>.  l=r=6

i=4 ==>  l=r=5

那么还应该求n%1*1,n%2*2,n%3*3,n%4*4

所以代码中的las就是标记还剩下几个没有取余

代码:

#include <iostream>#include <cstdio>#include <cmath>using namespace std;#define ll __int64const ll MOD=1e9+7;int main(){    ll n,m;    scanf("%lld%lld",&n,&m);    ll ans=(n%MOD)*(m%MOD)%MOD;    ll temp=0,las=m+1;    m=min(n,m);    ll nn=(ll)sqrt(n*1.0);    for (ll i=1;i<=nn;i++)    {        ll l = n/(i+1)+1;        ll r = n/i;        r=min(r,m);        if (l>r) continue;        las=min(las,l);        ll s1=l+r , s2 =(r-l+1);        if (s1%2==0) s1/=2;        else s2/=2;        s1%=MOD;s2%=MOD;        s1=(s1*s2)%MOD;        s1=s1*i%MOD;        temp=(temp+s1)%MOD;    }    ans=(ans+MOD-temp)%MOD;    for (ll i=1;i<las;i++)    {        temp=n/i%MOD*i%MOD;        ans=(ans+MOD-temp)%MOD;    }    printf("%lld\n",ans);    return 0;}


0 0