1. 程式人生 > >B Gym 101652P Fear Factoring

B Gym 101652P Fear Factoring

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;
}