У меня есть n целых чисел, хранящихся в массиве a, например [0], a [1], ....., a [n-1], где каждый a[i] <= 10^12
и n <100
. Теперь мне нужно найти все простые множители LCM этих n целых чисел, т.е. LCM of {a [0], a [1], ....., a [n-1]}Как рассчитать все простые множители lcm из n целых чисел?
I есть метод, но мне нужен более эффективный.
Мой метод:
First calculate all the prime numbers up to 10^6 using sieve of Eratosthenes.
For each a[i]
bool check_if_prime=1;
For all prime <= sqrt(a[i])
if a[i] % prime[i] == 0 {
store prime[i]
check_if_prime=0
}
if check_if_prime
store a[i] // a[i] is prime since it has no prime factor <= sqrt(n)
Print all the stored prime[i]'s
Есть ли лучший подход к этой проблеме?
Я отправляю ссылку на проблему:
http://www.spoj.pl/problems/MAIN12B/
Ссылка на мой код: http://pastebin.com/R8TMYxNz
Решение:
Как полагает Даниэль Фишер мой код нужно несколько оптимизаций как более быстрое сито и некоторые незначительные модификации. После выполнения всех этих изменений я могу решить проблему. Это мой код принят на SPOJ, который взял 1,05 секунды:
#include<iostream>
#include<cstdio>
#include<map>
#include<bitset>
using namespace std;
#define max 1000000
bitset <max+1> p;
int size;
int prime[79000];
void sieve(){
size=0;
long long i,j;
p.set(0,1);
p.set(1,1);
prime[size++]=2;
for(i=3;i<max+1;i=i+2){
if(!p.test(i)){
prime[size++]=i;
for(j=i;j*i<max+1;j++){
p.set(j*i,1);
}
}
}
}
int main()
{
sieve();
int t;
scanf("%d", &t);
for (int w = 0; w < t; w++){
int n;
scanf("%d", &n);
long long a[n];
for (int i = 0; i < n; i++)
scanf("%lld", &a[i]);
map < long long, int > m;
map < long long, int > ::iterator it;
for (int i = 0; i < n; i++){
long long num = a[i];
long long pp;
for (int j = 0; (j < size) && ((pp = prime[j]) * pp <= num); j++){
int c = 0;
for (; !(num % pp); num /= pp)
c = 1;
if (c)
m[pp] = 1;
}
if ((num > 0) && (num != 1)){
m[num] = 1;
}
}
printf("Case #%d: %d\n", w + 1, m.size());
for (it = m.begin(); it != m.end(); it++){
printf("%lld\n", (*it).first);
}
}
return 0;
}
В случае, если кто-то в состоянии сделать это в лучшую сторону или каким-либо быстрый метод, пожалуйста, дайте мне знать.
Я думаю, что результаты вашей программы на C++ и моя программа на C очень похожи. Время пользователя от 8 прогонов шахты составляет 0,204 + 0,209 + 0,207 + 0,206 + 0,208 + 0,209 + 0,206 + 0,208 = 1,657 с и от 8 пробегов составляет 0,208 + 0,210 + 0,209 + 0,211 + 0,209 + 0,209 + 0,212 + 0,212 = 1.68s. Оба были скомпилированы с -03. Я провел 5 прогонов одного, отбросил первый запуск (пока кеш разогревался), затем побежал 5 из другого и отбросил первый прогон, а затем сделал все это снова. Система и реальность тоже были похожи. Данные испытаний были 100 из 999962000357 = (999979 * 999983, самые высокие два простых числа меньше 1000000). Mac Core 2 Duo 2,16 МГц. НТН – gbulmer