CodeForces - 616E Sum of Remainders (数论)大数取余求和 好题

来源:互联网 发布:2k18球员数据更新 编辑:程序博客网 时间:2024/05/22 03:24
CodeForces - 616E
Sum of Remainders
Time Limit: 2000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u

Submit Status

Description

Calculate the value of the sum: nmod1 + nmod2 + nmod3 + ... + nmodm. 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 amodb stands for the remainder after dividing a by b. For example 10mod3 = 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

Source

Educational Codeforces Round 5
//题意就不说了,直接上大神的思路了,很6的方法

题意:求解mi=1nmodi

思路:我们化简nmodi=nn/ii
这样原式 =nmmi=1(n/ii)
首先m<=n时,直接暴力,对于剩下的,我们可以分块来搞,总会存在一段连续的值使得n/i为定值,那么我们找到这个区间就可以了。不过貌似在除以2的时候,会出问题,我直接上逆元就过了。

#include<cstdio>#include<cmath>#include<iostream>#include<cstdlib>#include<cstring>#include<queue>#include<algorithm>#define IN __int64#define M 1000000007using namespace std;IN kp(IN a, IN n) {IN ans = 1;while(n){if(n&1)ans=ans*a%M;a=a*a%M;n>>=1;}return ans;}int main(){IN n,m,sum,ans1,i,j,nn;while(scanf("%I64d%I64d",&n,&m)!=EOF){sum=n%M*(m%M)%M;nn=sqrt(n);ans1=0;for(i=1;i<=min(m,nn);i++)ans1=(ans1+n/i%M*i%M)%M;if(m>nn){if(nn*nn==n)nn--;for(i=1;i<=nn;i++){IN r=min(m,n/i);IN l=n/(i+1)+1;if(l>r||r<=nn)continue;ans1=(ans1+(l+r)%M*((r-l+1)%M)%M*kp(2,M-2)%M*i%M)%M;}}printf("%I64d\n",(sum-ans1+M)%M);}return 0;}


 

0 0