01/10/2018, 00:42
Thuật toán tính tổng các ước của 1 số nguyên dương?
**Mấy a cho e hỏi hướng để tỉm tổng các ước của 1 số LỚN nguyên dương 1 cách nhanh nhất được không ạ ? **
![](/pictures/picfullsizes/2018/10/01/dji1538407640.png)
e dùng code thế này vẫn đúng nhưng đếm rất chậm , và e nghĩ mãi không có hướng nào để làm nữa
#include<iostream>
using namespace std;
int main()
{
int n,s=0;;cin>>n;
for(int i=1;i<n;i++)
{
if(n%i==0) s+=i;
}
cout<<s;
return 0;
}
Bài liên quan
Bạn cho i chạy tới căn bậc 2 của n thôi, nếu chia hết thì cộng thêm i và n / i vào.
tks anh nhé vietha1996
chỗ đk :
làm sao xảy ra số i và j được nhỉ j=n/i mà…@@
Trường hợp này để kiểm tra những số chính phương.
Ví dụ n = 9, khi cho i chạy đến 3 thì j = n / i = 3
=> như vậy ước số 3 sẽ bị cộng 2 lần.
chạy đến
n/2
thôi bạn, không nhất thiết phải chạy đếnn
đâu vì ước của 1 số luôn <= 1/2 số đó trừ chính nóBài này có thể dùng phân tích thừa số nguyên tố
Người ta kí hiệu tổng ước là sigma(n) (sigma thường nhé).
Nếu n = p^k với p là số nguyên tố thì sigma(n) = 1 + p + p^2 + … + p^k = (p^(k+1) - 1)/(p-1).
Tổng quát hóa như sau: Cho q là một số nguyên tố sao cho gcd(q, n) = 1. Vậy ước của nq^k’ sẽ có dạng (ước của n)q^i với 0<=i<=k’. Vậy
sigma(nq^k’) = sigma(d|n) (dsigma(q^k’)). (sigma hoa :D) = sigma(q^k) * sigma(d|n) (d) = sigma(n) * sigma(q^k).
Từ đây suy ra sigma(n) = tích các sigma (thường) của thừa số nguyên tố.
Biến tổng có lẽ nên là 64 bit cho chắc ăn.
xin góp ý với các bạn,anh, chị ở đây là: ước số của 1 số nguyên dương thì luôn có 2 giá trị đối nhau, 1 âm và 1 dương, do đó tổng luôn bằng 0. nhưng giả sử đề ở đây ko phải là tổng các ước số mà là tích các ước số thì cho em hỏi là phải code như nào để lấy được tích của cả ước âm và dương ạ?
Đề thường chỉ nói đến ước dương thôi, ít ai nói đến ước âm.
Lấy danh sách các ước dương, các ước âm chỉ là đối của các ước dương.
Đếm xem n có bao nhiêu ước, nếu số ước lẻ thì tích các ước (cả âm và dương) sẽ âm, ngược lại tích các ước sẽ dương.
Lấy bình phương tích các ước dương, rồi nhân với dấu (đã biết dựa vào số ước của n).
em code thế này được ko nhỉ? thử lại với vài số thì cũng ra kqua đúng
Nếu n=10000 thì sao? Tích có thể nằm gọn trong khoảng int được không?
vậy phải sửa int thành gì ạ?
Ở đây lại có một dạng đối khác [spoiler]p và n/p[/spoiler]
Vậy thì phân tích thừa số để đếm ước và [spoiler]kt bình phương[/spoiler] là đủ.
là sao ạ?
đây là anh đang nói về bài toán tính tổng hay tích các ước ạ?
nếu là tính tổng thì mặc định là tổng bằng 0 nếu tính cả ước âm rồi, còn phân tích thừa số làm gì cho mệt ạ?
ví dụ ước của 2 là: -2,-1,1,2 thì tổng bao giờ chả bằng 0
Đang nói về tính tích mà. Vì vậy mới “có một dạng đối khác”.
em nghĩ như vậy là tự làm khó nó lên thôi mà, cụ thể nhé, ví dụ n=10; cho 1 ước bằng 2 thì ý anh có phải dạng đối khác ở đây là 10/2=5 đúng ko ạ? vậy cũng có giải quyết đc gì, ta cứ viết code tìm ước dương của nó, sau đó tính tích các ước thì nhân với giá trị âm tương ứng thôi
trên kia có 1 anh bảo sửa i vì n bằng 10000 thì quá tải, em nghĩ code như này là cũng ổn rồi
đây, em cop nhầm
Vậy là bạn chưa rõ rồi. Khi chia cho p thì đồng thời thu được n/p và ngược lại, nên không hề vô ích. Để không bị trùng, ta chọn p là số bé hơn, vậy thì chỉ cần chia tới … ? là được
Ngoài ra, khi đã biết p với n/p kết thành cặp (p * n/p = n), thì khi tính tích ta chỉ cần quan tâm đến số ước. Bạn quay lên trên sẽ thấy ngay bài mình viết 1 năm trước về cái này.