Ключом к решению этой проблемы является осознание того факта, что «квадрат» в «быстром возведении по квадратам» не является магическим числом: это могут быть кубы или любая сила, которая вам нужна. Эта конкретная проблема требует возведения в степень по кубам, хотя, поскольку b
записан в нотации base-3.
относительно легко расширить классический алгоритм работы с кубиками:
#include <cstdio>
#include <cstdlib>
#include <cstring>
typedef long long i64;
int main(int argc, char* argv[]) {
char buf[1024];
fgets(buf, sizeof(buf), stdin);
int t = atoi(buf);
while (t--) {
fgets(buf, sizeof(buf), stdin);
char* b;
i64 a = strtol(buf, &b, 10);
// b points to the first space; find the second space
b = strchr(++b, ' ');
// This is where m begins
i64 m = atoi(b--);
a %= m;
i64 res = 1;
// We process b starting from the back
while (*b != ' ') {
if (*b == '1') {
res *= a;
} else if (*b == '2') {
// The part that differs from the classic algorithm is here:
res *= a*a;
}
res %= m;
// We do exponentiation by cubes, hence it's a*a*a
a = (a * a * a) % m;
// End of the interesting part
b--;
}
printf("%d\n", (int)res);
}
return 0;
}
Проблема в SPOJ устанавливается таким образом, что делает C++ I/O непозволительно медленно, так что вся эта раздражает манипуляции с характером указатели, к сожалению, необходимы.
Это домашнее задание? Также ответ - быстрое возведение в степень *. – Alexander
нет только для практики, пожалуйста, дайте поэтапное решение не можете определить, что делать – user1217059
Есть также две проблемы с быстрым возведением в степень: 1.b может идти вверх до 3^250, поэтому вычисления a^b могут быть нечувствительными. 2.b находится в базе 3, соревнуясь с базой 10 будет стоить много, я думаю – user1217059