Алгоритм делителей

Мне дан список целых чисел (до 1000), которые умножаются на заданное целое число n.

Мне нужно найти наибольшую степень среди всех делителей целого числа n.

Например: 4,7,8 умножаем на 224, и тогда максимальная степень будет 5, так как 224 = 2 ^ 2 * 7 * 2 ^ 3 = 2 ^ 5 * 7.

Проблема в том, что 1000 целых чисел могут достигать 2 ^ 64, следовательно, n очень велико.

Какой отличный алгоритм для решения этой проблемы?


person Community    schedule 30.10.2016    source источник
comment
Это вопрос с подвохом. Наибольший простой множитель каждого из целых чисел (включая сами целые числа, если они простые) всегда будет таким же, как наибольший простой множитель их произведения. Фундаментальная математика.   -  person Sam Varshavchik    schedule 30.10.2016
comment
На самом деле я ищу не наибольшее простое число, а наибольшую степень всех простых чисел, то есть наибольшее k такое, что d ^ k делит n для всех d. Это max {k такое, что d ^ k | n, где d - делитель n}   -  person    schedule 30.10.2016
comment
Неважно. После вычисления простых чисел каждого числа вам просто нужно их сложить. Например, в примере с 4, 7 и 8 вы получите 2 * 2, 7, 2 * 2 * 2. У вас там пять двойок, это ваш ответ. Вам не нужно умножать их вместе, просто разложите каждое целое число на множители по отдельности и сложите их вместе. Базовая математика.   -  person Sam Varshavchik    schedule 30.10.2016
comment
Что ж ... На самом деле это то, что я сделал, я объяснил свой подход, разложив каждое число на множители, затем подсчитав количество простых чисел и взяв максимум. Он отлично работает для небольших чисел, как в примере, но давайте возьмем, например, 985528436837146801 (как одно из этих 1000 чисел). Мне потребовалось 7 секунд, чтобы разложить его на множители.   -  person    schedule 30.10.2016
comment
Тогда это не более чем вопрос о наиболее эффективном способе нахождения простых множителей числа. Я уверен, что есть много вопросов по этой теме, где-то здесь ... Запустите поиск в Google по запросу "Сито Эратотена".   -  person Sam Varshavchik    schedule 30.10.2016
comment
Я уже искал сита (сита Эратосфена и Аткина), и проблема, с которой я столкнулся, заключается в том, что мне нужно сгенерировать простые числа до 10 ^ 9 в качестве предварительного вычисления. Но сохранение их в векторе и повторение по ним снова занимает много времени.   -  person    schedule 30.10.2016
comment
@SamVarshavchik: Неправильно. Когда шаги по решению проблемы занимают много времени, не думайте, как я могу сделать этот шаг быстрее, подумайте, как я могу решить проблему без этого шага.   -  person gnasher729    schedule 30.10.2016
comment
@SamVarshavchik: И решето совершенно бесполезно, чтобы найти множители одного большого числа или найти множители 1000 чисел до 2 ^ 64.   -  person gnasher729    schedule 30.10.2016
comment
Похоже, вы не можете сделать намного быстрее, иначе вы могли бы использовать свой метод для массовой факторизации целых чисел.   -  person n. 1.8e9-where's-my-share m.    schedule 30.10.2016
comment
Почему этот код нужно оптимизировать или оптимизировать?   -  person Thomas Matthews    schedule 30.10.2016
comment
Его необходимо оптимизировать, потому что цикл for (в частности, часть i=i+2) проверяет каждое нечетное число до квадратного корня из числа. Это примерно 1 миллиард делений, когда входное число состоит из 18 цифр. На это уходит много времени.   -  person user3386109    schedule 30.10.2016
comment
Чтобы ответ был больше 1, входные данные должны быть либо точным квадратом, либо входными данными должны быть не менее 3 множителей. Если входные данные являются точным квадратом, вам нужно только иметь возможность разложить на множители квадратный корень из числа, для чего требуется список простых чисел до корня четвертой степени из числа. Если у числа есть 3 фактора, то хотя бы один из этих факторов должен быть меньше или равен кубическому корню из числа. Есть другие детали, которые нужно проработать, но вы сможете решить проблему, учитывая список простых чисел меньше 2642246.   -  person user3386109    schedule 30.10.2016
comment
@ user3386109 В чем проблема с ровно двумя факторами?   -  person    schedule 30.10.2016
comment
Если в числе ровно 2 множителя, то какова наибольшая степень среди делителей?   -  person user3386109    schedule 31.10.2016
comment
@ user3386109, то не проверяйте все нечетные числа. Ознакомьтесь с простыми колесами и теоремой о простых числах.   -  person Michael Foukarakis    schedule 25.12.2016


Ответы (1)


Трудный. Сначала я бы начал проверять маленькие простые числа (в вашем примере: 4, 7, 8. У произведения есть множитель 2 ^ 5. Вы делите на степени двойки, оставляя 1, 7, 1. Затем вы делаете то же самое для 3 , 5, 7 и т. Д. До X).

Теперь вам нужно найти большее простое число p> X, которое является большей степенью, чем наибольшее число, которое вы нашли. Тратить много времени на поиск основных факторов, которые встречаются только один раз, кажется расточительным. Вам нужны простые числа, которые являются множителями нескольких чисел. Вычислите НОД каждой пары чисел и посмотрите на простые множители этих чисел. Есть много деталей, которые нужно проработать, поэтому я начал со «сложного».

В худшем случае вы не можете легко найти какое-либо простое число, которое встречается дважды, поэтому вам нужно проверить, содержит ли каждое из чисел квадрат простого числа в качестве множителя.

В качестве примера: вы проверили множители до 1000 и обнаружили, что наибольшая степень простого числа равна 83 ^ 3. Итак, теперь вам нужно найти большее простое число в четвертой степени или показать, что его нет. Вычислите попарные НОД (наибольший общий делитель). Большое простое число может быть делителем нескольких этих НОД, полученных от четырех разных чисел, или p может быть множителем трех НОД, с p ^ 2 множителем одного числа и т. Д.

Чтобы прояснить принцип: скажем, у вас есть два ОГРОМНЫХ числа x и y, и вы хотите знать, какое из них является наибольшей степенью простого числа, которое делит xy. Вы можете разложить на множители x и y и перейти оттуда. Если они оба являются простыми числами или произведением двух больших простых чисел, скажем, x = p или pq, а y = r или rs, это займет много времени.

Теперь вычислите НОД x и y. Если наибольший общий делитель равен z> 1, то z является делителем x и y, поэтому z ^ 2 является делителем xy. Если наибольший общий делитель равен 1, то x и y не имеют общего делителя. Поскольку нам не нужны неквадратные множители, мы ищем квадраты и множители более высокого порядка. Для этого вам нужно всего лишь разделить на множители до x ^ (1/3) или y ^ (1/3).

person gnasher729    schedule 30.10.2016
comment
@Guru: Вам вообще не нужно множить это большое число, если оно не имеет общего множителя с каким-либо другим числом, поскольку, если это простое число или множитель двух больших простых чисел, но у него нет общего множителя с любым другим числом, вы получаете только степень 1. Вам может потребоваться квадратные множители, если вы не можете найти никаких квадратов, но для этого требуются множители только до 3 миллионов. - person gnasher729; 30.10.2016
comment
Я пытаюсь понять ваш подход .. Но что, если вход состоит из 500-кратного числа 985528436837146801. Результат должен быть 1000, потому что полученное целое число равно 992737849 ^ 1000 .. - person ; 30.10.2016
comment
Вы быстро обнаружите, что все числа имеют множитель 985528436837146801, так что вы знаете, что у вас есть 500-я степень. Затем вам нужно проверить, является ли 985528436837146801 квадратом или имеет квадратный множитель. Проверить, что он квадратный, очень быстро. Чтобы проверить, есть ли квадратный множитель, вам нужно только удалить множители до x ^ (1/3). - person gnasher729; 30.10.2016
comment
Если вы тратите 6-7 секунд на факторизацию 985528436837146801, то у вас уже есть проблема с эффективностью вашего алгоритма факторизации. Вторым возвращением поискового факторизованного числа в Интернете был веб-сайт, который нашел решение 992737849 * 992737849 менее чем за 0,005 секунды. Таким образом, сокращения времени факторизации может быть достаточно для решения ваших проблем с TLE. - person Penguino; 31.10.2016