#c #math #modular-arithmetic
#c #математика #модульная арифметика
Вопрос:
Сегодня я практиковался с головоломкой «быстрая мощность», в которой использовалась формула: (a * b) % p = (a % p * b % p) % p
для вычисления (a^n)%p
, что-то вроде этого: 2^31 % 3 = 2
Однако я так смущен, когда нашел ответ, используемый ((temp * temp) % b * a) % b;
для решаемой ситуации, когда n нечетно, например 2^3
(temp (temp * temp) % b * a
рекурсивно или (temp * temp) % b
).
Разве это не должно быть ((temp * temp) % b * a%b) % b
?
Поскольку в соответствии с этой формулой все должно %b
быть до времени вместе.
Комментарии:
1. Как это вопрос c ??
2. Разве вы не видите, что в этом вопросе есть одна строка кода? Пожалуйста, также проверьте ответ ниже.
3. Нет! Конечно, не то, что я могу скомпилировать! … Приведенный ниже ответ — хороший пример, которому вы должны следовать, чтобы отформатировать свой вопрос..
4. Хорошо.. Я буду иметь это в виду. Спасибо, чувак
Ответ №1:
Разве это не должно быть
((temp * temp) % b * a % b) % b
?
Нет. Поскольку a
, если вы заранее знаете, что a
это не будет переполняться (a меньше b), вам не нужно его модифицировать.
Идея заключается в том, что модульная арифметика работает для сложения и умножения. Операции типа (a b) % M = (a % M b % M) % M
и (a * b) % M = (a % M * b % M) % M
обычно выполняются, чтобы избежать переполнения (a * b)
и (a b)
и сохранить значение в определенном диапазоне.
Пример:
const int Mod = 7;
int a = 13;
int b = 12;
int b = b % Mod; // b now contains 5 which is certainly smaller than Mod
int x = (a % Mod * b) % Mod; // you won't need to mod b again if you know beforehand b is smaller than Mod
Обновить
C реализация степенной функции:
#define MOD 1000000007
// assuming x and n both be positive and initially smaller than Mod
int power(int x, int n) {
if(n == 0) return x;
int half = power(x, n / 2) % Mod;
int ret = (half * half) % Mod; // you didn't need to do (half % Mod * half % Mod) % Mod because you already know half is smaller than Mod and won't overflow.
// Modulas being performed on the multiplied output, so now ret will be smaller than Mod
if(n amp; 1) {
ret = (ret * x) % Mod; // you didn't need to do (ret % Mod * x % Mod) % Mod
// because you already know ret and x is smaller than Mod
}
return ret;
}
Мод — это дорогостоящая операция. Поэтому вам следует избегать этого, когда это возможно.
Комментарии:
1. ВАУ, потрясающе! То есть вы имеете в виду, что для выполнения операции% на самом деле не требуется одно единственное число? Потому что кажется, что в формуле каждое число выполняет операцию%