#F. Divisible sum

topic


train of thought

This question is an obvious divisible block problem.

The same value in the table will appear continuously, and the interval product divided by the same value is an integer divisible block.

The nature of divisibility makes the array table from 1 to n can be divided into different blocks according to the value, and the number of blocks is much smaller than n.

Using this property, if we can deduce where the specific left and right endpoints of each block are, this problem can be solved quickly.

Assuming that we know the left endpoint L of a certain block, we need to solve the right endpoint R of the block.

Let the value of the block be K, then k = ⌊ n/ L ⌋

Since each number i in the interval [L, R] satisfies ⌊ n/ i ⌋=k

So the right boundary R is the largest i that satisfies the condition i*K<=N, that is, R=⌊n/k⌋=⌊n/(⌊n/ L⌋) ⌋


the code

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

Guess you like

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