как получить модуль значения в экспоненциальной форме

Вопрос об операторе по модулю на очень больших числах.

Например, рассмотрим вопрос, в котором необходимо рассчитать общее количество перестановок. Рассмотрим число из 90 цифр, в котором каждое из 9 чисел (от 1 до 9) повторяется 10 раз, поэтому нужно вычислить 90!/(10!)^9).

Прочитав много ответов на StackOverflow, я использовал для этого логарифмы.

Теперь рассмотрим значение журнала как 1923.32877864.

Теперь мой вопрос: как я могу отобразить ответ (т.е. 10 ^ log10 (значение)) по модулю «m»?

И это лучший метод для расчета возможного количества перестановок?

Изменить Есть решение :)

Благодаря duedl0r.

Сделал это так, как вы указали, используя Modular Multiplicative Inverse.Спасибо :)


person anudeep2011    schedule 03.02.2012    source источник
comment
Является ли m целым числом, которое соответствует 31 биту?   -  person Sergey Kalinichenko    schedule 03.02.2012
comment
Является ли m простым или, по крайней мере, взаимно простым с 10!?   -  person Kerrek SB    schedule 03.02.2012
comment
да, он подходит для 31-битного .. 10 ^ 9 максимум.   -  person anudeep2011    schedule 03.02.2012
comment
m составляет 10 ^ 9 + 7 для этого конкретного вопроса (это со спой-сайта)   -  person anudeep2011    schedule 03.02.2012
comment
Если вам действительно нужен целочисленный модуль, то использование журналов - НЕПРАВИЛЬНЫЙ способ сделать это. Обратите внимание, что результат БУДЕТ целым числом, поэтому вы можете просто использовать форму большого целого числа.   -  person    schedule 03.02.2012


Ответы (2)


Я не уверен, что это действительно возможно и правильно, но позвольте мне обобщить мои комментарии и расширить ответ Мики Динеску.

Как уже писал Мики:

a × b ≣m am × bm

Вы можете использовать это в своем равенстве:

90! / 10!^9 ≣м х

Вычислите каждый член:

90!м / 10!^9мм х

Затем найдите свой обратный мультипликатив от 10!^9m. Затем умножьте обратное значение на 90!m.


update Это кажется правильным (по крайней мере, для этого случая :)). Я проверил с вольфрамом:

(90!/10!^9) mod (10^9+7) = 998551163

Это приводит к тому же результату:

90! mod (10^9+7) = 749079870
10!^9 mod (10^9+7) = 220052161

сделать обратное:

(220052161 * x) mod(10^9+7) = 1 = 23963055

потом:

(749079870*23963055) мод (10^9+7) = 998551163

Никаких доказательств, но некоторые доказательства того, что это может сработать :)

person duedl0r    schedule 03.02.2012
comment
Получил решение :) Спасибо duedl0r. Сделал это так, как вы указали, используя Modular Multiplicative Inverse. Спасибо :) - person anudeep2011; 03.02.2012

Я бы сказал, что способ вычислить общее количество перестановок по модулю m, где m — произвольное целое число (обычно выбираемое как большое простое число), заключается в использовании следующего свойства:

 (a * b) % m = ((a % m) * (b % m)) % m

Учитывая, что общее количество перестановок N равно N! = 1 * 2 * 3 * .. * N, если вам нужно вычислить N! % m, вы можете по существу применить указанное выше свойство для умножения по модулю m, и у вас есть:

 ((((1 * (2 % m)) % m) * (3 % m)) % m) * .. 

ИЗМЕНИТЬ

Чтобы вычислить 90! / (10! ^ 9), вы можете упростить множители, а затем использовать умножение по модулю m для вычисления окончательного результата по модулю m.

Вот что я думаю:

90! = 10! * (11 * 12 * .. * 20) * (21 * 22 * .. * 30) * .. * (81 * 82 * .. * 90)

Затем вы можете переписать исходное выражение как:

(10! * (11 * 12 * .. * 20) * (21 * 22 * .. * 30) * .. * (81 * 82 * .. * 90)) / (10! * 10! * ... * 10!)

В числителе у вас есть произведение 9 множителей, учитывая каждое выражение в скобках как множитель. То же самое верно и для знаменателя (у вас есть 9 множителей, каждый из которых равен 10!).

Первый множитель в знаменателе легко упростить. После этого у вас остается 8 пар, которые нуждаются в упрощении.

Таким образом, вы можете факторизовать каждый член произведений и упростить знаменатель. Например:

11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20 <=> 11 * 2 * 2 * 3 * 13 * 2 * 7 * 3 * 5 * 2 * 2 * 2 * 2 * 17 * 2 * 9 * 2 * 2 * 5

Знаменатель всегда будет: 2 * 3 * 2 * 2 * 5 * 2 * 3 * 7 * 2 * 2 * 2 * 2 * 3 * 3 * 2 * 5

После упрощения вторая пара сводится к: 2 * 2 * 11 * 13 * 17 * 19

То же самое можно применить к каждой последующей паре, и вы получите простое произведение, которое можно вычислить по модулю m, используя приведенную выше формулу.

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

person Mike Dinescu    schedule 03.02.2012
comment
Как вы вычисляете 90!/10!^9 с этим? (90! % m) / 10!^9 выглядит неправильно.. или даже если вы возьмете 10^1923.32, у вас возникнут проблемы, так как 1923,32 не четное число.. - person duedl0r; 03.02.2012
comment
именно так, как сказал duedl0r. это проблема, с которой я столкнулся. как я могу работать с делениями.. если это сделано, в основном получается 0, как числитель ‹ знаменатель. - person anudeep2011; 03.02.2012
comment
Я думаю, вы можете умножить на 10! ^ 9. Но в этом решении это не упоминается... что-то вроде этого: 90!%m = x*(10!^9%m) %m. Затем найдите x :) - person duedl0r; 03.02.2012
comment
возможно, вы даже можете использовать Эйлера, чтобы получить обратное. > - person duedl0r; 03.02.2012
comment
хм, кажется, я упустил важный аспект вашего вопроса @anudeep2011. Я помню, что существовал метод вычисления модульной экспоненты с нецелочисленными показателями, но я не могу точно вспомнить, как он работает. Модульное возведение в степень с целыми показателями легко. - person Mike Dinescu; 03.02.2012