<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=185.127.225.126&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=185.127.225.126&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/185.127.225.126"/>
		<updated>2026-08-19T10:35:34Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0_%D0%BC%D0%BD%D0%BE%D0%B6%D0%B8%D1%82%D0%B5%D0%BB%D0%B8_(%D1%84%D0%B0%D0%BA%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F)&amp;diff=80705</id>
		<title>Разложение на множители (факторизация)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0_%D0%BC%D0%BD%D0%BE%D0%B6%D0%B8%D1%82%D0%B5%D0%BB%D0%B8_(%D1%84%D0%B0%D0%BA%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F)&amp;diff=80705"/>
				<updated>2021-03-13T23:14:02Z</updated>
		
		<summary type="html">&lt;p&gt;185.127.225.126: Отмена правки 80691, сделанной 213.87.242.44 (обсуждение)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение | definition=&lt;br /&gt;
'''Факторизация''' (англ. ''factorization'') — представление объекта в виде произведения других объектов.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение | definition=&lt;br /&gt;
'''Разложение на множители''', или '''Факторизация целых чисел''' (англ. ''integer factorization'') — представление числа в виде [[Натуральные числа#Основная теорема арифметики | произведения его множителей]].&lt;br /&gt;
}}&lt;br /&gt;
== Перебор делителей==&lt;br /&gt;
{{Определение | definition=&lt;br /&gt;
'''Перебор делителей''' (англ. ''Trial division'') — алгоритм, ПРИДУМАННЫЙ ГЕРМАНОМ ДЛЯ ГЛУПОЙ факторизации или тестирования простоты числа путем полного перебора всех возможных потенциальных делителей.&lt;br /&gt;
}}&lt;br /&gt;
=== Наивная реализация O(n) ===&lt;br /&gt;
[[Основная теорема арифметики#Основная теорема арифметики#Собственно теорема | Основная теорема арифметики]], вкупе с утверждением, что  &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; не делит &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; нацело: &amp;lt;tex&amp;gt;\forall x, y \in \mathbb{N}~~x&amp;lt;y \Longrightarrow&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;\left( \dfrac{x}{y} &amp;lt; 1 \right)&amp;lt;/tex&amp;gt;, позволяют нам ограничить пространство поиска делителей числа &amp;lt;tex&amp;gt;number&amp;lt;/tex&amp;gt; интервалом &amp;lt;tex&amp;gt;[2;number]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
==== Основная идея ====&lt;br /&gt;
Заметим, что если &amp;lt;tex&amp;gt;number&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;\prod p_i = p_1 \cdot p_2 \cdot \ldots \cdot p_{j-1} \cdot p_j \cdot p_{j+1} \cdot \ldots \cdot p_n&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\left(\dfrac{number}{p_j}\right) = \prod\limits_{i \ne j} p_i = p_1 \cdot p_2 \cdot \ldots \cdot p_{j-1} \cdot p_{j+1} \cdot \ldots \cdot p_n&amp;lt;/tex&amp;gt;. Таким образом, мы можем делить &amp;lt;tex&amp;gt;number&amp;lt;/tex&amp;gt; на его делители (множители)  последовательно и в любом порядке. Тогда будем хранить &amp;lt;tex&amp;gt;curNum \colon curNum = \dfrac{number}{\prod result_i}&amp;lt;/tex&amp;gt; — произведение оставшихся множителей.&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод нахождения простых множителей ====&lt;br /&gt;
Так как простых множителей не может быть больше, чем &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, а в худшем случае (когда число простое, и на каждое итерации &amp;lt;tex&amp;gt;probe&amp;lt;/tex&amp;gt; увеличивается на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;) он работает за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, то, следовательно, алгоритм работает за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' getMultipliers(number: '''int'''): '''vector&amp;lt;int&amp;gt;'''&lt;br /&gt;
       &amp;lt;font color=green&amp;gt;// сюда складываем множители&amp;lt;/font&amp;gt;&lt;br /&gt;
       result = '''vector&amp;lt;int&amp;gt;'''&lt;br /&gt;
       &amp;lt;font color=green&amp;gt;// число, у которого осталось найти множители&amp;lt;/font&amp;gt;&lt;br /&gt;
       curNum = number&lt;br /&gt;
        &amp;lt;font color=green&amp;gt;// число, на которое пытаемся делить&amp;lt;/font&amp;gt;&lt;br /&gt;
       probe = 2&lt;br /&gt;
       '''while''' curNum &amp;lt;tex&amp;gt;\ne&amp;lt;/tex&amp;gt; 1&lt;br /&gt;
           '''if''' curNum '''mod''' probe &amp;lt;tex&amp;gt;\ne\, &amp;lt;/tex&amp;gt;0&lt;br /&gt;
               &amp;lt;font color=green&amp;gt;// проверены все множители из [2; probe]&amp;lt;/font&amp;gt;&lt;br /&gt;
               probe++&lt;br /&gt;
           '''else'''&lt;br /&gt;
               &amp;lt;font color=green&amp;gt;// делим пока делится&amp;lt;/font&amp;gt;&lt;br /&gt;
               curNum /= probe&lt;br /&gt;
               result += [probe]&lt;br /&gt;
        '''return''' result&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод нахождения делителей ====&lt;br /&gt;
&lt;br /&gt;
    '''function''' getDividers(number: '''int'''): '''vector&amp;lt;int&amp;gt;'''&lt;br /&gt;
        &amp;lt;font color=green&amp;gt;// массив полученных делителей&amp;lt;/font&amp;gt;&lt;br /&gt;
        result = '''vector&amp;lt;int&amp;gt;''' &lt;br /&gt;
        &amp;lt;font color=green&amp;gt;// перебираем все потенциальные делители&amp;lt;/font&amp;gt;&lt;br /&gt;
        '''for''' probe = 2 '''to''' number&lt;br /&gt;
            '''if''' number '''mod''' probe = 0&lt;br /&gt;
                &amp;lt;font color=green&amp;gt;// probe делит number нацело&amp;lt;/font&amp;gt;&lt;br /&gt;
                result += [probe]&lt;br /&gt;
        '''return''' result&lt;br /&gt;
&lt;br /&gt;
=== Улучшенная реализация &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
==== Основная идея ====&lt;br /&gt;
Из определения: &amp;lt;tex&amp;gt;\sqrt{n} \cdot \sqrt{n} = n&amp;lt;/tex&amp;gt;. Логично, что:&lt;br /&gt;
{|&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;| &amp;lt;tex&amp;gt;\bigg\{&amp;lt;/tex&amp;gt;&lt;br /&gt;
|&amp;lt;tex&amp;gt;x \cdot y = number&amp;lt;/tex&amp;gt;&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;| &amp;lt;tex&amp;gt;\Longrightarrow x &amp;gt; \sqrt{number}&amp;lt;/tex&amp;gt; &lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;lt;tex&amp;gt;y &amp;lt; \sqrt{number}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Таким образом, любой делитель &amp;lt;tex&amp;gt;d_0 &amp;gt; \sqrt{number}&amp;lt;/tex&amp;gt; однозначно связан с некоторым &amp;lt;tex&amp;gt;d_1 &amp;lt; \sqrt{number}&amp;lt;/tex&amp;gt;. Если мы найдем все делители до &amp;lt;tex&amp;gt;\sqrt{number}&amp;lt;/tex&amp;gt;, задача может считаться решенной.&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
&lt;br /&gt;
    '''function''' getDividers(number: '''int'''): '''vector&amp;lt;int&amp;gt;'''&lt;br /&gt;
         result = '''vector&amp;lt;int&amp;gt;'''&lt;br /&gt;
         '''for''' probe = 2 '''to''' &amp;lt;tex&amp;gt;\sqrt{number}&amp;lt;/tex&amp;gt; &amp;lt;font color=green&amp;gt;//обновляем верхнюю границу перебора&amp;lt;/font&amp;gt;&lt;br /&gt;
            '''if''' number '''mod''' probe = 0&lt;br /&gt;
                result += [probe]&lt;br /&gt;
                result += [number / probe] &amp;lt;font color=green&amp;gt;// записываем сопряженный делитель&amp;lt;/font&amp;gt;&lt;br /&gt;
        '''return''' result&lt;br /&gt;
&lt;br /&gt;
=== Проверка числа на простоту ===&lt;br /&gt;
Алгоритм можно переделать для нахождения простых чисел. Число будет простым, если у него не окажется множителей (и делителей) кроме &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (алгоритмы не проверяют делимость на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;) и самого числа (улучшенная реализация опускает этот делитель).&lt;br /&gt;
&lt;br /&gt;
== Предподсчет ==&lt;br /&gt;
{{main|Решето Эратосфена}}&lt;br /&gt;
=== Основная идея ===&lt;br /&gt;
Решето Эратосфена (англ. ''Sieve of Eratosthenes'') позволяет не только находить простые числа, но и находить простые множители числа. Для этого необходимо хранить (помимо самого &amp;quot;решета&amp;quot;) массив простых чисел, на которое каждое число делится (достаточно одного простого делителя).&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;font color=green&amp;gt;// возвращает только дополнительный массив&amp;lt;/font&amp;gt;&lt;br /&gt;
    '''function''' sieveOfEratosthenes(n: '''int'''): '''int'''[n + 1]&lt;br /&gt;
        result = [n + 1]&lt;br /&gt;
        result[n] = n&lt;br /&gt;
        &amp;lt;font color=green&amp;gt;// выбираем следующий простой делитель&amp;lt;/font&amp;gt;&lt;br /&gt;
        '''for''' i  = 2 '''to''' &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''if''' result[i] = 0&lt;br /&gt;
                &amp;lt;font color=green&amp;gt;// записываем делитель в элементы массива,&lt;br /&gt;
                // соответствующие числа которых делятся нацело&amp;lt;/font&amp;gt;&lt;br /&gt;
                shuttle = &amp;lt;tex&amp;gt;i^2&amp;lt;/tex&amp;gt;&lt;br /&gt;
                '''while''' shuttle &amp;lt;tex&amp;gt;\leqslant&amp;lt;/tex&amp;gt; n&lt;br /&gt;
                    result[shuttle] = i&lt;br /&gt;
                    shuttle += i&lt;br /&gt;
        '''return''' result&lt;br /&gt;
&lt;br /&gt;
    '''function''' getMultipliers(number: '''int'''): '''vector&amp;lt;int&amp;gt;'''&lt;br /&gt;
        result = '''vector&amp;lt;int&amp;gt;'''&lt;br /&gt;
        &amp;lt;font color=green&amp;gt;// получаем дополненное решето Эратосфена&amp;lt;/font&amp;gt;&lt;br /&gt;
        sieve = sieveOfEratosthenes(number)&lt;br /&gt;
        &amp;lt;font color=green&amp;gt;// следующее временное значение получаем&lt;br /&gt;
        // делением предыдущего на простой делитель из решета&amp;lt;/font&amp;gt;&lt;br /&gt;
        curNum = number&lt;br /&gt;
        '''while''' curNum &amp;lt;tex&amp;gt;\ne&amp;lt;/tex&amp;gt; 1&lt;br /&gt;
            result += sieve[curNum]&lt;br /&gt;
            curNum /= sieve[curNum]&lt;br /&gt;
        '''return''' result&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Решето Эратосфена]]&lt;br /&gt;
*[[Основная теорема арифметики]]&lt;br /&gt;
*[[Дискретная математика, алгоритмы и структуры данных#Комбинаторика | Комбинаторика]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Маврин П.Ю. — Лекция по алгоритмам над простыми числами (2016)&lt;br /&gt;
* [https://ru.wikipedia.org/wiki/Простое_число https://ru.wikipedia.org/wiki/Простое_число]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы алгебры и теории чисел]]&lt;br /&gt;
[[Категория: Теория чисел]]&lt;/div&gt;</summary>
		<author><name>185.127.225.126</name></author>	</entry>

	</feed>