#G. Find the sixth of the divisor


We first find the sum of all divisors between the interval [1..b]

Then the result is equal to

The sum of all divisors between [1..b] minus the sum of divisors between [1..a-1]

Obviously these two problems are of the same nature, only the right endpoints are different.

Obviously, for numbers between 1 and N, the divisor range is also within the range of 1 to N.

So we can enumerate the approximate number L. Of course, this enumeration cannot be a for loop enumeration, but it is "jumping" like the above question

So N/L represents how many numbers between 1 and N are multiples of L, and L must also be their divisor.

For example, when L=7, N=20

N/20=2, indicating that there are two numbers within 1 to 20 that are multiples of 7, which are easily known as 7 and 14, which means that when calculating the sum of the divisors of 7 and 14, 7 must be counted.

Then the cleverness of this algorithm is that

When L=8,9,10, N/L=2

So L=7, R=10 in this section

So the sum of the divisors in this section is 2*7+2*8+2*9+2*10=2*(7+8+9+10)=2*(7+10)*(10-7+ 1)/2

After counting this section, set L=R+1=10+1=11

You will find that 11 is used as an approximate number, and it will only appear once

At the same time, it will also be found that the approximate numbers of 12, 13, 14....... 20 in this section will only appear once


#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m;
ll f(ll x)
{
  ll l = 1,r = 0,k = 0,ans = 0,m = 0;
  while(l <= x)
  {
    r = x / (x / l);
    k = x / l;
    ans += k * (l + r) * (r - l + 1) / 2;
    l = r + 1;
  }
  return ans;
}
signed main()
{
  cin>>n>>m;
  cout<<f(m) - f(n - 1);
  return 0;
}

Guess you like

Origin blog.csdn.net/weq2011/article/details/129191269