Zeldain Garden(除法分块:o(sqrt(n)))

链接:https://ac.nowcoder.com/acm/contest/7817/E
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

Boris is the chief executive officer of Rock Anywhere Transport (RAT) company which specializes in supporting music industry. In particular, they provide discount transport for many popular rock bands. This time Boris has to move a large collection of quality Mexican concert loudspeakers from the port on the North Sea to the far inland capital. As the collection is expected to be big, Boris has to organize a number of lorries to assure smooth transport. The multitude of lorries carrying the cargo through the country is called a convoy. 

Boris wants to transport the whole collection in one go by a single convoy and without leaving even a single loudspeaker behind. Strict E.U. regulations demand that in the case of large transport of audio technology, all lorries in the convoy must carry exactly the same number of pieces of the equipment. 

To meet all the regulations, Boris would like to do some planning in advance, despite the fact that he does not yet know the exact number of loudspeakers, which has a very significant influence on the choices of the number and the size of the lorries in the convoy. To examine various scenarios, for each possible collection size, Boris calculates the so-called “variability”, which is the number of different convoys that may be created for that collection size without violating the regulations. Two convoys are different if they consist of a different number of lorries. 

For instance, the variability of the collection of 6 loudspeakers is 4, because they may be evenly divided into 1, 2, 3, or 6 lorries.

输入描述:

The input contains one text line with two integers N, M (1 ≤ N ≤ M ≤ 10 12 ), the minimum and the maximum number of loudspeakers in the collection.

输出描述:

Print a single integer, the sum of variabilities of all possible collection sizes between N and M,inclusive.

示例1

输入

复制2 5

2 5

输出

复制9

9

示例2

输入

复制12 12

12 12

输出

复制6

6

示例3

输入

复制555 666

555 666

输出

复制852

852

题意:求区间[n,m]的每个数的因子个数之和。

思路:除法分块

结论:[1,n]的所有数的因子个数之和等价于1-n这n个因子的出现次数之和,即:

\sum_{i=1}^{n}n/i  (n/i向下取整),即:i这个因子在1-n的因子中出现的次数为:n/i

如:1-12这12个因子在1-n的所有因子中出现的次数分别为:12 6 4 3 2 2 1 1 1 1 1 1

可以发现有连续的区间因子出现次数是相同的,如[7,12]这6个因子在1-n的所有因子中出现的次数都是1,所有可以直接1*(12-7+1)来计算这些因子的个数此时,只需要用当前次数*等于此次数的区间长度即可计算其对答案的贡献。

这样问题就转化成了要求每段连续的出现次数相同的因子所在区间:

通过找规律可以发现,可以首先设区间左端点l=1,右端点r=n/(n/l),然后只要l<=n,每次让l=r+1即可。

时间复杂度:o(sqrt(n))

代码:

#include 
#include 
#include 

#define int long long

using namespace std;

int n,m;

int get_num(int n)
{
    int l=1,r,res=0;
    while(l<=n){
        r=n/(n/l);
        res+=n/l*(r-l+1);
        l=r+1;
    }
    return res;
}

signed main()
{
    cin>>n>>m;
    cout<

拓展:如果是求[1,n]的所有数的因子之和,答案就变成了1-n这n个因子的出现次数*i的和:

\sum_{i=1}^{n}(n/i)*in/i向下取整,即:每次加上i这个因子在1-n的因子中出现的次数*i

在求的时候,同样对于因子出现次数是相同的连续的区间,如[7,12]这6个因子在1-n的所有因子中出现的次数都是1,所有可以直接1*(7+8+9+10+11+12)=1*[(7+12)*(12-7+1)/2]来计算这些因子的个数此时,只需要用当前次数*因子构成的等差数列的和即可计算其对答案的贡献。

 

你可能感兴趣的:(数论)