题目链接在此
转自这位大神
1.乘法求模:
(1)模数不大的时候可利用性质(a*b)%c = (a%c)*(b%c)%c
(2)模数和两乘数都很大的时候,可用以下算法(暂时还没弄清原理和理论来源,就当个模板吧):
long long mulAndMod(long long a, long long b, long long mod) { // a * b % mod
long long c;
const int base = 2; // base可以取任意大于1的整数
for (c = 0; b != 0; b /= base) {
c += (b % base) * a;
c %= mod;
a = (a * base) % mod;
}
return c;
}
2. 关于解法具体算法,仔细揣摩一下就能看懂代码,另外可以参考上述大神的博客中的解释。
</pre><p><span style="white-space:pre"></span><pre name="code" class="cpp">#include <iostream>
#include <string>
using namespace std;
long long mulAndMod(long long a, long long b, long long mod) { // a * b % mod
long long c;
const int base = 2; // base可以取任意大于1的整数
for (c = 0; b != 0; b /= base) {
c += (b % base) * a;
c %= mod;
a = (a * base) % mod;
}
return c;
}
long long cube(long long x, long long mod){ // x^3 % y = (x^2 % y) * x % y
return mulAndMod(mulAndMod(x, x, mod), x, mod);
}
int main() {
int t;
long long result; // 答案,从右向左一位位增加
long long remain; // 从右向左一位位地和待比较的数比较
long long power;
long long step;
string str; // 待比较的数
int length; // 待比较数的长度
cin >> t;
while (t--){
cin >> str;
length = str.length();
remain = str[length - 1] - '0'; // 初始化,取待比较的数最低位
if (remain == 1) result = 1; // 待比较的数最低位若为1,则答案最低位为1
else if (remain == 3) result = 7; // 待比较的数最低位若为3,则答案最低位为7
else if (remain == 7) result = 3; // 待比较的数最低位若为7,则答案最低位为3
else if (remain == 9) result = 9; // 待比较的数最低位若为9,则答案最低位为9
power = 10;
for (int i = length - 2; i >= 0; --i){ // 从待比较数的倒数第二位开始
remain += (str[i] - '0') * power; // 更新remain值
step = power;
power *= 10; // 若remain有两位,则模数为100;若remain有三位,则模数为1000……
// (result^3 % power)与remain比较,直到相等。此时result低位中对应remain的那几位已经确定
while (cube(result, power) != remain){
// 若remain有两位,则result每次加10即可;若remain有三位,则result每次加100即可……
result += step;
}
}
cout << result << '\n';
}
return 0;
}