本文共 733 字,大约阅读时间需要 2 分钟。
#includeusing namespace std;typedef long long ll;const int mod = 1e9 + 7;ll n,k;ll run(ll x){ ll j;/*i是前界,j是后界*/ ll res = 0; for(ll i = 2;i <= min(x,k);i = j + 1){ ll y = x / i; j = min(x / y,k); /*右边界大于k在同一个n/i的数量上会有变化,会多加上几个n/i 右边界是可以大于k的,而且情况还不少,所以有时候不能直观去看 */ res = (res + ((j - i + 1) * y) % mod); } return res;}int main(){ scanf("%lld%lld",&n,&k); ll sum = 0; sum += n + k - 1; //如果数论分块会加上n + n - 1 //k不一定等于n,与实际不符 sum = (sum + run(n) + run(n - 1)) % mod; printf("%lld\n",sum); return 0;}/*这道题是什么意思呢就是通过观察,我们可以知道(n,k)-->(nk,k) 第一个整数一定是第二个整数的倍数(n,k)-->(nk+1,k)令n = xk(第一个整数一定是k的倍数);1. n == xk2. n == xk + 1那么n == xk 或n - 1 == xk所以这道题就转化成了是求n / k(k = 1,2,3... )的和方法就是数论分块*/
转载地址:http://isox.baihongyu.com/