Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.92/64: Рейтинг темы: голосов - 64, средняя оценка - 4.92
5 / 5 / 1
Регистрация: 30.07.2011
Сообщений: 257

A^B mod C

06.08.2011, 20:50. Показов 13356. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Найти A^B mod C. Тут как-то надо использовать рекурсию. Кто может помочь?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.08.2011, 20:50
Ответы с готовыми решениями:

Нужно посчитать a^x * m mod p и b/(a^x) mod p
Нужно посчитать a^x * m mod p. Где a, x, m, p(простое число) - очень большие числа. И нужно посчитать b/(a^x) mod p. Программа типа ...

mod
Здравствуйте! У меня вопрос наверное глупый. Препод для выбора курсовой поставил следующие условия: Вариант задания выбирается по формуле...

mod ^И
//----- остаток неправильный printf("%d %d",9%3,9&2); //0 0 printf("%d %d",1%3,1&2); //1 0 //----- в то же время следующее...

22
 Аватар для Roof
155 / 155 / 44
Регистрация: 03.11.2010
Сообщений: 393
06.08.2011, 21:34
Рекурсию нужно использовать при возведении в степень.
Насколько я понял эту запись, то сначала A возводится в степень B, потом от полученного результата находим остаток от деления на C.
Один из самых простых вариантов, работает только со степенями >= 0.
Есть такая оговорка: если один из операндов оператора % ( остаток от деления ) отрицательный, то результат получится зависимый от машины.
Т.е. нужно предусматривать:
- чтобы либо все числа A, B и C были положительными,
- либо если число A отрицательно, то степень B должна быть четная и число C положительно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
 
int pow_xy( int x, int y ) {
    if ( y == 0 )
        return 1;
    else
        return x * pow_xy( x, y - 1 );
}
 
int main() {
    int a, b, c;
    cout << "Введите a" << endl;
    cin >> a;
 
    cout << "Введите b" << endl;
    cin >> b;
 
    cout << "Введите c" << endl;
    cin >> c;
 
    cout << "Результат: " << ( pow_xy( a, b ) %c ) << endl;
    return 0;
}
0
Заблокирован
06.08.2011, 21:36
я думал ^ это xor o_0
1
Higher
 Аватар для diagon
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
06.08.2011, 21:38
Цитата Сообщение от Roof Посмотреть сообщение
Рекурсию нужно использовать при возведении в степень.
Насколько я понял эту запись, то сначала A возводится в степень B, потом от полученного результата находим остаток от деления.
Один из самых простых вариантов, работает только со степенями >= 0.
Есть такая оговорка: если один из операндов оператора % ( остаток от деления ) отрицательный, то результат получится зависимый от машины.
Т.е. нужно предусматривать:
- чтобы либо все числа A, B и C были положительными,
- либо если число A отрицательно, то степень B должна быть четная и число C положительно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
 
int pow_xy( int x, int y ) {
    if ( y == 0 )
        return 1;
    else
        return x * pow_xy( x, y - 1 );
}
 
int main() {
    int a, b, c;
    cout << "Введите a" << endl;
    cin >> a;
 
    cout << "Введите b" << endl;
    cin >> b;
 
    cout << "Введите c" << endl;
    cin >> c;
 
    cout << "Результат: " << ( pow_xy( a, b ) %c ) << endl;
    return 0;
}
a = 1000, b = 10000 ?
Могу ошибаться, но тут нужно хранить в А только последние n чисел, n зависит от C(количество разрядов в С + 1).
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
06.08.2011, 21:41
если погуглить, то поятно, что задача олимпиадная и идет речь об математической закономерности
задача дается на большие числа
1
5 / 5 / 1
Регистрация: 30.07.2011
Сообщений: 257
06.08.2011, 21:42  [ТС]
Roof, A,B,C<10^9 как возводить то?
0
 Аватар для Roof
155 / 155 / 44
Регистрация: 03.11.2010
Сообщений: 393
06.08.2011, 21:44
2 CAHTEXHUKну - да, это xor, а я поторопился.
2 AvengerAlive - я решил, что это простая задачка учебная, которая ограничивается небольшими числами, но, видимо, ошибся.
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
06.08.2011, 21:45
Roof,
Цитата Сообщение от alex_x_x Посмотреть сообщение
адача олимпиадная и идет речь об математической закономерности
0
 Аватар для Roof
155 / 155 / 44
Регистрация: 03.11.2010
Сообщений: 393
06.08.2011, 21:50
2 alex_x_x - нагуглил, увидел, спасибо.
0
5 / 5 / 1
Регистрация: 30.07.2011
Сообщений: 257
06.08.2011, 21:52  [ТС]
CAHTEXHUK, ^ возведение в степень не в С

Roof, лонг лонг заработал только ошибку даёт на больших значениях
0
 Аватар для Roof
155 / 155 / 44
Регистрация: 03.11.2010
Сообщений: 393
06.08.2011, 22:01
2 AvengerAlive - мой алгоритм неверен для больших чисел.
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
06.08.2011, 22:13
Вот, переделал из обычного возведения в степень, надеюсь ничего лишнего не выкинул в процессе.
Идея в том, чтобы представить возведение в степень в виде возведений в квадрат и умножений на основание. Например
https://www.cyberforum.ru/cgi-bin/latex.cgi?5^{11} =  5\Bigl(5\bigl(5^2\bigr)^2\Bigr)^2
Операцию приведения по модулю надо выполнять после каждой промежуточной операции, чтобы не возникало переполнения.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
 
unsigned pow(unsigned a, unsigned b, unsigned m)
{
    unsigned n = 0;
    unsigned k = 1;
    unsigned long long res;
    if (0 == a)
        return 0;
    if (0 == b)
    return 1;
 
    while ( (n = k << 1) <= b && n )
        k = n;
    if (0 == n)
        return 0;
    res = a;
    k >>= 1;
    while (k)
    {
        res = (res*res) % m;
        if (k & b)
            res = (res*a) % m;
        k >>= 1;
    }
    return (unsigned)(res);
}
 
int main()
{
    unsigned a;
    unsigned b;
    unsigned m;
    scanf("%u%u%u", &a, &b, &m);
    printf("%u**%u mod %u = %u\n", a, b, m, pow(a, b, m));
    return 0;
}
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
06.08.2011, 22:22
чегото вроде
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
 
unsigned f( unsigned a, unsigned now_b, unsigned c )
{
   std::cout << a << " " << now_b << std::endl;
   switch( now_b )
   {
     case 1: return a;
     case 2: return a*a;
     default: 
     {
        unsigned  left_b_power = now_b / 2, 
                  right_b_power = now_b - left_b_power;
        return f( a, left_b_power, c ) * f( a, right_b_power, c ) % c;
     }
   }
}
 
int main()
{
   std::cout << f( 15, 15, 34 );
}
это по свойству (A*B) mod C = ((A mod C)*(B mod C)) mod C

Добавлено через 6 минут
долговато на больших числах выходит
0
5 / 5 / 1
Регистрация: 30.07.2011
Сообщений: 257
06.08.2011, 22:53  [ТС]
grizlik78, спасибо, тесты 2^31 прошёл, а вот 2^63 под unsigned long long уже не получается...
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
06.08.2011, 22:55
AvengerAlive, в смысле если операнды 63 бита длиной? так я этого не обещал.
Когда показания на ходу меняются — я так не играю
Цитата Сообщение от AvengerAlive Посмотреть сообщение
Roof, A,B,C<10^9 как возводить то?
0
385 / 229 / 12
Регистрация: 06.07.2011
Сообщений: 512
07.08.2011, 00:10
если ^ все-таки возведение в степень, то используется модулярная арифметика. возведение A в степень B по модулю C это повторяющееся умножение A на A по модулю С B раз. А умножение по модулю C это повторяющееся сложение A и A по модулю С.

если в коде, A,B и С большие положительные числа:

сложение по модулю (т.е. получаем именно (A+B)%C)
C++
1
2
3
4
long long int addition (long long int A, long long int B, long long int C) {
if (C-A<B) return ((((A>>1)+(B>>1))%(C>>1))<<1)+(A&1)+(B&1)-(C&1);
return (A+B)%C;
}
умножение по модулю:
C++
1
2
3
4
5
6
7
8
9
long long int mulptiplication (long long int A, long long int B, long long int C) {
long long int remainder = 0;
while (B) {
  if (B&1) remainder=addition(A,remainder,C);
  A=addition(A,A,C);
  B>>=1;
}
return remainder;
}
возведение в степень по модулю:
C++
1
2
3
4
5
6
7
8
9
10
long long int power (long long int A, long long int B, long long int C) {
long long int remainder = 1;
if (!B) return -1;
while (B) {
  if (B&1) remainder=multiplication(A,remainder,C);
  A=multiplication(A,A,C);
  B>>=1;
}
return remainder;
}
0
5 / 5 / 1
Регистрация: 30.07.2011
Сообщений: 257
07.08.2011, 09:38  [ТС]
grizlik78, да нет, unsigned long long переименовал переменные просто, на больших не заработал... придётся длинную арифметику делать. А за код спасибо)
0
 Аватар для Olga_
848 / 190 / 18
Регистрация: 01.08.2011
Сообщений: 505
07.08.2011, 11:38
Все работает, даже 2^63

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
unsigned long long Degree(unsigned long long a, unsigned long long b, unsigned long long c)
{
   unsigned long long deg, rez;
   rez = 1;
   deg = a;
   while (b)
   {
      if (b & 1)
      {
         rez *= deg;
         rez %= c;
      }
      deg *= deg;
      deg %= c;
      b >>= 1;
   }
   return rez;
}
Если модуль c не нужен, удалите строки

unsigned long c
rez %= c;
deg %= c;

Добавлено через 34 минуты
Если модуль c не больше 2^64-1, то этим алгоритмом можно вычислять хоть числа 500^10000 mod 12345, 2^12356789 mod 100000 и т.д.
0
5 / 5 / 1
Регистрация: 30.07.2011
Сообщений: 257
07.08.2011, 12:24  [ТС]
Olga_, спасибо, теперь то хоть вместо Ошибка выполнения, Неверный ответ пишет... Значит уже пошло дело к лучшему...
0
 Аватар для Olga_
848 / 190 / 18
Регистрация: 01.08.2011
Сообщений: 505
07.08.2011, 12:43
Цитата Сообщение от AvengerAlive Посмотреть сообщение
Olga_, спасибо, теперь то хоть вместо Ошибка выполнения, Неверный ответ пишет... Значит уже пошло дело к лучшему...
Как это, а вы на чем тестировали?

Добавлено через 11 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <cstdlib>
#include <iostream>
#include <clocale>
using namespace std;
 
 unsigned long long Degree(unsigned long long a, unsigned long long b, unsigned long long c)
{
   unsigned long long deg, rez;
   rez = 1;
   deg = a;
   while (b)
   {
      if (b & 1)
      {
         rez *= deg;
         rez %= c;
      }
      deg *= deg;
      deg %= c;
      b >>= 1;
   }
   return rez;
}
 
int main(int argc, char* argv[])
{
   cout << Degree(2, 63, 1 << 64 - 1);
   getchar();
   return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
07.08.2011, 12:43
Помогаю со студенческими работами здесь

mod (на C)
нужно проверить число на нечётность я сделал так: if (k mod 2 == 1) &lt;действия&gt; но компилятор выдал ошибку типа:syntax error...

DIv MOD в С++
не подскажете как описать оператор ДИВ в С++? суть такова а=5 b=2 x=a DIV 2 y=5/2 printf(...x) (y) мне нужно...

div и mod
Помогите, пожалуйста: вводимое с клавиатуры число n нужно разделить следующим образом (n, n1, n2 - целые ): если n четное, то n1 = n2 =...

Div и mod в С++
Здравствуйте. Перехожу из паскаля в c++. Есть отрывок кода который проверяет есть ли в числе N цифра 3 и есть ли в числе вводимое с...

Операция mod()
Подскажите, pls, как осуществить операцию m mod n (вычисление остатка) не используя операцию деления в процессе вычисления?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru