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