em bỏ cái minPrime trong sumofdiv thì với mỗi i từ L tới R nó tính lại minPrime cho i từ đầu, tốn O(i * log(log(i)))
, R - L + 1
lần như vậy thì ko biết nó ra bao nhiêu nhưng có lẽ là O(n^2 loglog(n))
với n = R - L + 1
chạy thẳng cái minPrime ở ngoài thì chỉ tốn 1 lần O(n loglog(n))
, mỗi lần chạy tính sumofdiv bây giờ chỉ tốn O(log(i))
cho cái vector a
còn cái tính sum thì ko biết nhưng cao lắm cũng cỡ O(log(i))
Tổng coogj R - L + 1
lần chỉ tốn O(n logn)
, cộng lại chỉ còn O(n loglog(n)) + O(n log(n))
= O(n log(n))
truyền tham chiếu để khỏi phải copy lại cái minPrime. Mấy cuộc thi kiểu này nó chơi minPrime là biến toàn cục luôn khỏi mất công truyền tham chiếu… Ở đây mình muốn giới hạn phạm vi minPrime tối đa, chỉ tồn tại trong main() nên phải truyền tham chiếu vô sumofdiv.
với lại lần sau đọc code hiểu nó muốn làm gì cái đã, 1 chức năng = 1 hàm, đừng gộp chung vào. minPrime ra 1 hàm, prime factors ra 1 hàm. Cái đống này:
vector<int> analyzation;
while(n != 1)
{
analyzation.push_back(minPrime[n]);
n /= minPrime[n];
}
đáng lẽ phải tách ra 1 hàm riêng, đừng viết nó ở trong sumofdiv. vì nó có nhiệm vụ riêng. sumofdiv chỉ cần input 1 cái vector primeFactors
) rồi output sum of divs
int sumOfDivisors(const vector<int>& primeFactors); //muốn tìm tổng ước nhanh cần các ước nguyên tố
//vector<int> primeFactors(int n); //chậm, O(n^0.5)
vector<int> primeFactors(int n, const vector<int>& minPrime); //nhanh, O(logn), cần phải có 1 mảng minPrime
vector<int> minPrime(int max);
rồi implement từng cái là đc
tl;dr quăng ra ngoài thì nó là O(a) + O(b), bỏ vào trong thì nó thành O(a*b)