题意:计算 n mod 1+n mod 2 + ... n mod m
思路:其实计算 n mod x 可以转换为 n - [n/x]*x n/x=i 是一个连续的范围 比如 10/4 =2 10/5=2 我们只要计算出 n/x=i 的一个范围 ,就可以用等差公式求和了
ps :上网查了一下 有开方的策略 好像才是正确姿势 = = 代码太丑 爆了好多次LL
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define N 100010
#define MOD 1000000007
#define LL long long
LL n,m,ans;
LL divide2(LL x,LL y)
{
if(x%2==0)
return (((x/2)%MOD)*(y%MOD))%MOD;
else
return ((x%MOD)*((y/2)%MOD))%MOD;
}
int main()
{
scanf("%lld%lld",&n,&m);
ans=((max(0LL,m-n)%MOD)*(n%MOD)%MOD+MOD)%MOD;
for(LL i=n,j=1,k=1,l=1;i>0;l+=k)
{
ans=((ans+(n%MOD)*(k%MOD)-(i%MOD)*divide2(k+j-1+j,k)%MOD)%MOD+MOD)%MOD;
if(l>=m)break;
i=min(i-1,n/(k+j));
j=k+j;
if(i==0)break;
k=min(n/i-j+1,m-j+1);
}
/*
LL ans2=0;
for(LL i=1;i<=m;i++)
ans2=(ans2+n%i)%MOD;
*/
printf("%lld\n",ans);
return 0;
}