http://codeforces.com/problemset/problem/616/E
刷题真的是一个积累知识点的过程,如果不刷这道题,永远都想不到应该是把%运算换一种表达形式进行计算
题意:对于给定n,m求sum,sum = n % 1 + n % 2 + ... + n % m
由于数据过大,1e13,所以暴力肯定不可取,解题思路是回归到模运算的本质上去
*a % b = a - b*(a/b)
题解链接,博客里讲得很清楚,这里就不赘述了,数论对公式的推导真的很严格,而且如果是我知道了思路之后,也一定会第一时间定义两个变量模拟l和r,然而博主只用了一个变量r,这种问题真的是先想明白了再做的好啊,能省去大把大把的时间
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#define ll long long
#define mod 1000000007
#define inf 0x3f3f3f3f
using namespace std;
#define ll long long
using namespace std;
int main()
{
ll n, m;
ll r;
cin>>n>>m;
ll ans1 = ((n%mod)*(m%mod))%mod;
m = min(n, m);//n/i,大于n的部分等于零无意义不用求
ll ans = 0;
//i模拟左边界,r模拟右边界
for(ll i = 1; i <= m; i ++)
{
r = min(n/(n/i), m);
//cout<<r<<endl;
ll a = i + r;
ll b = r - i + 1;
if(a%2) b/=2;
else a/=2;
ans = (ans + ((a%mod)*(b%mod)%mod)*(n/i)%mod)%mod;//等差数列求和
i = r;//执行完此次for循环自动加一
}
cout<<(ans1 - ans + mod) % mod<<endl;
return 0;
}