B    Gym 101652P    Fear Factoring

这题求 b , a之间 所有数包括他的因子和。

看一眼肯定知道是筛选所有的因子。

a,b不超过 1e6。a , b ,不超过 1e12,1e6*1e6刚好1e12

所以我们枚举  1-1e6所有的数 ,然后求分别以这个为因子会出现的次数。

然后用 ,a 出现的因子和 -b 里面出现的因子和。

加入我们要求 x=10 里面所有的因子和。

首先  10/1 =10 所有以1为因子的 另一个因子 最大是10.

枚举 一下好理解就是   1= 1*1   2=2*1  3=3*1 4=4*1 5=5*1 … 10=10*1.

就是  从 所有数和  (1 +2+3+4+……+10) (这个时候不用把 自己这个因子加进去,因为后面以其他数为因子还会再算一次,这样会重复

然后  10/2=5  所有以 2为 因子的另一个因子最大是 5.

枚举一下:2=1*2,4=2*2,6=3*2,8=4*2,10=5*2;

所有数的和 就是  (1+2+3+4+5)

同理 10/3=3       所有以 3 为因子另一个因子和是 (1+2+3)

以此类推后面所有因子的和就可以得结果。

但是你会发现过不去样例 3 … … 因为你只枚举到了1e6 万一 x>1e6,会出现

以这个(1e6+1)为 因子的,另一个因子的和就没有加上去,所以就要反过来。

原本是确定一个因子 求另一个因子所有的数的和,这次我们就求一个因子总共出现多少次。

例如   x= 1e8,原本已经求了 以 1-1e6为因子然后另一个因子的和,就相当于,把出现少于 1e6次数以下的全部加上了。所以出现少于 1e6次以下的都不用加了,只需要以上的首先枚举  1-1e6;

1   x/1=1e8,   1出现了 1e 8 次前面以及算了 1e6次 所以 以 1为因子还需要加上的次数是 1e8-1e6,  和是  (1e8-1e6)*1;

同理  2   x/2=5e7,2出现了5e7次   所有数的和是  (5e7-1e6)*2;

以此类推 2 3 4 直到 1e6   因为a,b<1e12  ,所以 最多到 1e6不可能再多了,

还有一个问题如果 x=1e12,  求 以1为因子的时候 是 最大因子是1e12

求和的话是   (1+1e12)*1e12/2 这个明显炸longlong 了,如果你会开 int128后面就不用看了。

这个题目给的数据b-a不超过 1e6 ,可以直接求,k1=(b+i-1)/i (这个要向上取整)  ,k2=a/i;

然后所有数的和是  (k2-k1+1)*(k2+k1)/2 这样就不会炸 long long

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
    ll b,a,res=0;
    cin>>b>>a;
    for(int i=1; i<=1e6; i++) {
        ll k1=(b+i-1)/i,k2=a/i;
        if(k1>k2)continue;
        res+=(k2-k1+1)*(k2+k1)/2;

    }
    for(int i=1; i<=1e6; i++) {
        if(n/i>=1e6) {
            ll k=max((ll)1e6,(m-1)/i);
            res+=(n/i-k)*i;
        }
    }
    cout<<res<<endl;
}