максимальное число делителей - у степеней двойки, так что просто
находишь ближайшие степень двойки <= N
[code]
|
Код:
|
if (colors[p] == 2) marked.Add(new MarkedItem { index = p, iter = (uint)i - 2 }); |
неудивительно что жутко тормозит. нельзя пользоваться аллокатором во внутреннем цикле!!!!!! которой стопицот мильонов раз будет выполняться!!!!!!!
Вот что я имел ввиду
|
Код:
|
user@magrathea:~/tmp$ cat p.cc
#include <cstdio>
#include <cstdlib>
#include <cstring>
typedef unsigned long long ui64;
int main(int argc, char **argv)
{
ui64 N = atoi(argv[1]);
char *table = new char[N+1];
memset(table, 0, N+1);
for (ui64 p = 2; p <= N; p++) {
if (table[p] == 0) {
for (ui64 pp = p; pp <= N; pp *= p) { // цикл по степеням p
for (ui64 q = pp; q <= N; q += pp) {
++table[q];
}
}
}
}
//....
return 0;
}
user@magrathea:~/tmp$ g++ -o p p.cc -O3 -Wall -W
p.cc:7: warning: unused parameter 'argc'
user@magrathea:~/tmp$ time ./p 1000000
real 0m0.013s
user 0m0.006s
sys 0m0.007s
user@magrathea:~/tmp$ time ./p 10000000
real 0m0.156s
user 0m0.164s
sys 0m0.012s
user@magrathea:~/tmp$ time ./p 100000000
real 0m2.828s
user 0m2.767s
sys 0m0.048s
user@magrathea:~/tmp$ time ./p 1000000000
real 0m34.574s
user 0m33.804s
sys 0m0.609s
user@magrathea:~/tmp$ time ./p 2000000000
real 1m17.109s
user 1m15.548s
sys 0m1.256s |
это без вывода хлама на диск, но мысль думаю ясна